Re: [PATCH v4 5/7] dmaengine: dw: drain the tasklet before releasing channel resources

From: Frank Li

Date: Fri Oct 30 2026 - 11:29:58 EST


On Thu, Oct 29, 2026 at 04:29:39PM -0600, James Hilliard wrote:
> The controller tasklet invokes callbacks after dropping the channel lock.
> Releasing a channel can therefore clear its configuration and disable the
> controller while that tasklet run is still using them.
>
> Disable the tasklet before clearing channel resources and re-enable it
> after updating the controller's in-use mask. This waits for an executing
> run while preserving pending schedules for the other channels. Have a
> pending run return before accessing registers when the last channel has
> already been released.
>
> Fixes: 3bfb1d20b547 ("dmaengine: Driver for the Synopsys DesignWare DMA controller")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
> ---

Reviewed-by: Frank Li <Frank.Li@xxxxxxx>

> drivers/dma/dw/core.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
> index 1d6419e1cd3c..3bda85adbeee 100644
> --- a/drivers/dma/dw/core.c
> +++ b/drivers/dma/dw/core.c
> @@ -398,6 +398,10 @@ static void dw_dma_tasklet(struct tasklet_struct *t)
> u32 status_err;
> unsigned int i;
>
> + /* Channel release may have drained a polled completion before this run. */
> + if (!dw->in_use)
> + return;
> +
> status_xfer = dma_readl(dw, RAW.XFER);
> status_err = dma_readl(dw, RAW.ERROR);
>
> @@ -1067,6 +1071,8 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
> struct dw_dma *dw = to_dw_dma(chan->device);
> unsigned long flags;
>
> + tasklet_disable(&dw->tasklet);
> +
> dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
> dwc->descs_allocated);
>
> @@ -1092,6 +1098,8 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
> if (!dw->in_use)
> do_dw_dma_off(dw);
>
> + tasklet_enable(&dw->tasklet);
> +
> dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
> }
>
>
> --
> 2.53.0
>