Hi Claudiu,
-----Original Message----- From: Claudiu claudiu.beznea@tuxon.dev Sent: 23 December 2025 13:50 Subject: [PATCH v6 2/8] dmaengine: sh: rz-dmac: Move CHCTRL updates under spinlock
From: Claudiu Beznea claudiu.beznea.uj@bp.renesas.com
Both rz_dmac_disable_hw() and rz_dmac_irq_handle_channel() update the CHCTRL register. To avoid concurrency issues when configuring functionalities exposed by this registers, take the virtual channel lock. All other CHCTRL updates were already protected by the same lock.
Previously, rz_dmac_disable_hw() disabled and re-enabled local IRQs, before accessing CHCTRL registers but this does not ensure race-free access. Remove the local IRQ disable/enable code as well.
Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC") Cc: stable@vger.kernel.org Signed-off-by: Claudiu Beznea claudiu.beznea.uj@bp.renesas.com
Reviewed-by: Biju Das biju.das.jz@bp.renesas.com
Cheers, Biju
Changes in v6:
- update patch title and description
- in rz_dmac_irq_handle_channel() lock only around the updates for the error path and continued using the vc lock as this is the error path and the channel will anyway be stopped; this avoids updating the code with another lock as it was suggested in the review process of v5 and the code remain simpler for a fix, w/o any impact on performance
Changes in v5:
- none, this patch is new
drivers/dma/sh/rz-dmac.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index c8e3d9f77b8a..818d1ef6f0bf 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -298,13 +298,10 @@ static void rz_dmac_disable_hw(struct rz_dmac_chan *channel) { struct dma_chan *chan = &channel->vc.chan; struct rz_dmac *dmac = to_rz_dmac(chan->device);
unsigned long flags;
dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index);
local_irq_save(flags); rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
local_irq_restore(flags);
}
static void rz_dmac_set_dmars_register(struct rz_dmac *dmac, int nr, u32 dmars) @@ -569,8 +566,8 @@ static int rz_dmac_terminate_all(struct dma_chan *chan) unsigned int i; LIST_HEAD(head);
- rz_dmac_disable_hw(channel); spin_lock_irqsave(&channel->vc.lock, flags);
- rz_dmac_disable_hw(channel); for (i = 0; i < DMAC_NR_LMDESC; i++) lmdesc[i].header = 0;
@@ -707,7 +704,9 @@ static void rz_dmac_irq_handle_channel(struct rz_dmac_chan *channel) if (chstat & CHSTAT_ER) { dev_err(dmac->dev, "DMAC err CHSTAT_%d = %08X\n", channel->index, chstat);
rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
scoped_guard(spinlock_irqsave, &channel->vc.lock) goto done; }rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);-- 2.43.0