[PATCH v3 32/34] dmaengine: hidma: defer callbacks via channel BH
Allen Pais <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel,org.infradead.lists.linux-arm-kernel,org.kernel.vger.dmaengine,org.kernel.vger.linux-arm-msm |
|---|---|
| Message-ID | <702687c28f440bf017c6e57f630bb65d22d3b217.1786384169.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..486a2c61a9fb 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) { + dmaengine_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); + dmaengine_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); + dmaengine_init_bh(&mchan->chan, hidma_chan_bh); INIT_LIST_HEAD(&mchan->free); INIT_LIST_HEAD(&mchan->prepared); -- 2.43.0