[PATCH v2 62/64] dmaengine: hidma: defer callbacks via channel BH
Allen Pais <[email protected]> Mon, 27 Jul 2026 13:39:24 -0700
| Newsgroups | org.kernel.vger.dmaengine,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <1648cb3a6b6c85009831e1dd263a6336bd31638a.1785183549.git.allen.lkml@gmail.com> |
Move descriptor callback processing out of the low-level completion path and schedule it through per-channel BH work. Drain that work while freeing channels so callbacks cannot outlive channel storage. Signed-off-by: Allen Pais <[email protected]> --- drivers/dma/qcom/hidma.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c index c939635be21d..1f875a499ab3 100644 --- a/drivers/dma/qcom/hidma.c +++ b/drivers/dma/qcom/hidma.c @@ -90,7 +90,13 @@ static inline struct hidma_chan *to_hidma_chan(struct dma_chan *dmach) static void hidma_free(struct hidma_dev *dmadev) { - INIT_LIST_HEAD(&dmadev->ddev.channels); + struct hidma_chan *mchan, *next; + + list_for_each_entry_safe(mchan, next, &dmadev->ddev.channels, + chan.device_node) { + dma_chan_kill_bh(&mchan->chan); + list_del(&mchan->chan.device_node); + } } static unsigned int nr_desc_prm; @@ -155,6 +161,13 @@ static void hidma_process_completed(struct hidma_chan *mchan) } } +static void hidma_chan_bh(struct dma_chan *chan) +{ + struct hidma_chan *mchan = to_hidma_chan(chan); + + hidma_process_completed(mchan); +} + /* * Called once for each submitted descriptor. * PM is locked once for each descriptor that is currently @@ -181,7 +194,7 @@ static void hidma_callback(void *data) } spin_unlock_irqrestore(&mchan->lock, irqflags); - hidma_process_completed(mchan); + dma_chan_schedule_bh(&mchan->chan); if (queued) { pm_runtime_mark_last_busy(dmadev->ddev.dev); @@ -203,6 +216,7 @@ static int hidma_chan_init(struct hidma_dev *dmadev, u32 dma_sig) mchan->dmadev = dmadev; mchan->chan.device = ddev; dma_cookie_init(&mchan->chan); + dma_chan_init_bh(&mchan->chan, hidma_chan_bh); INIT_LIST_HEAD(&mchan->free); INIT_LIST_HEAD(&mchan->prepared); -- 2.43.0