Re: [PATCH v3 18/34] dmaengine: xgene-dma: wire descriptor cleanup to dmaengine BH

From: Frank Li

Date: Wed Sep 02 2026 - 12:36:27 EST


On Mon, Aug 10, 2026 at 11:09:19AM -0700, Allen Pais wrote:
> Replace the per-channel tasklet with the shared dmaengine BH helper.
> The handler continues to run in softirq context while dmaengine owns
> the common scheduling and teardown mechanism.
>
> Signed-off-by: Allen Pais <allen.lkml@xxxxxxxxx>
> ---

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

> drivers/dma/xgene-dma.c | 19 +++++++++----------
> 1 file changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c
> index fa1173e49900..bdeed908e37a 100644
> --- a/drivers/dma/xgene-dma.c
> +++ b/drivers/dma/xgene-dma.c
> @@ -260,7 +260,6 @@ struct xgene_dma_desc_sw {
> * These descriptors have already had their cleanup actions run. They
> * are waiting for the ACK bit to be set by the async tx API.
> * @desc_pool: descriptor pool for DMA operations
> - * @tasklet: bottom half where all completed descriptors cleans
> * @tx_ring: transmit ring descriptor that we use to prepare actual
> * descriptors for further executions
> * @rx_ring: receive ring descriptor that we use to get completed DMA
> @@ -280,7 +279,6 @@ struct xgene_dma_chan {
> struct list_head ld_running;
> struct list_head ld_completed;
> struct dma_pool *desc_pool;
> - struct tasklet_struct tasklet;
> struct xgene_dma_ring tx_ring;
> struct xgene_dma_ring rx_ring;
> };
> @@ -975,9 +973,10 @@ static enum dma_status xgene_dma_tx_status(struct dma_chan *dchan,
> return dma_cookie_status(dchan, cookie, txstate);
> }
>
> -static void xgene_dma_tasklet_cb(struct tasklet_struct *t)
> +static void xgene_dma_tasklet_cb(struct dma_chan *c)
> {
> - struct xgene_dma_chan *chan = from_tasklet(chan, t, tasklet);
> + struct xgene_dma_chan *chan = container_of(c, struct xgene_dma_chan,
> + dma_chan);
>
> /* Run all cleanup for descriptors which have been completed */
> xgene_dma_cleanup_descriptors(chan);
> @@ -999,11 +998,11 @@ static irqreturn_t xgene_dma_chan_ring_isr(int irq, void *id)
> disable_irq_nosync(chan->rx_irq);
>
> /*
> - * Schedule the tasklet to handle all cleanup of the current
> + * Schedule the bottom half to handle all cleanup of the current
> * transaction. It will start a new transaction if there is
> * one pending.
> */
> - tasklet_schedule(&chan->tasklet);
> + dmaengine_schedule_bh(&chan->dma_chan);
>
> return IRQ_HANDLED;
> }
> @@ -1539,7 +1538,7 @@ static int xgene_dma_async_register(struct xgene_dma *pdma, int id)
> INIT_LIST_HEAD(&chan->ld_pending);
> INIT_LIST_HEAD(&chan->ld_running);
> INIT_LIST_HEAD(&chan->ld_completed);
> - tasklet_setup(&chan->tasklet, xgene_dma_tasklet_cb);
> + dmaengine_init_bh(&chan->dma_chan, xgene_dma_tasklet_cb);
>
> chan->pending = 0;
> chan->desc_pool = NULL;
> @@ -1556,7 +1555,7 @@ static int xgene_dma_async_register(struct xgene_dma *pdma, int id)
> ret = dma_async_device_register(dma_dev);
> if (ret) {
> chan_err(chan, "Failed to register async device %d", ret);
> - tasklet_kill(&chan->tasklet);
> + dmaengine_kill_bh(&chan->dma_chan);
>
> return ret;
> }
> @@ -1579,7 +1578,7 @@ static int xgene_dma_init_async(struct xgene_dma *pdma)
> if (ret) {
> for (j = 0; j < i; j++) {
> dma_async_device_unregister(&pdma->dma_dev[j]);
> - tasklet_kill(&pdma->chan[j].tasklet);
> + dmaengine_kill_bh(&pdma->chan[j].dma_chan);
> }
>
> return ret;
> @@ -1790,7 +1789,7 @@ static void xgene_dma_remove(struct platform_device *pdev)
>
> for (i = 0; i < XGENE_DMA_MAX_CHANNEL; i++) {
> chan = &pdma->chan[i];
> - tasklet_kill(&chan->tasklet);
> + dmaengine_kill_bh(&chan->dma_chan);
> xgene_dma_delete_chan_rings(chan);
> }
>
> --
> 2.43.0
>