BAM uses virt-dma to invoke client callbacks from a tasklet, but provides no device_synchronize callback. Its terminate callback removes descriptors from the channel lists; it cannot wait for a callback already spliced into the tasklet's local list. Likewise vchan_free_chan_resources does not wait for that tasklet. A client using dmaengine_terminate_sync can therefore release callback-owned data before the callback returns. Implement device_synchronize with vchan_synchronize. Clients must stop publishing new descriptors before calling synchronous termination, as the DMAEngine API requires. The BAM-DMUX client-side publication boundary is handled separately in this series. Found by the author's in-house static analysis tool. Fixes: e7c0fe2a5c84 ("dmaengine: add Qualcomm BAM dma driver") Cc: stable@vger.kernel.org Signed-off-by: Hongyan Xu Signed-off-by: Zehao Gao --- Discovery: found by the author's in-house static analysis tool. drivers/dma/qcom/bam_dma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index e62e411..8cee883 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -784,6 +784,11 @@ static int bam_dma_terminate_all(struct dma_chan *chan) return 0; } +static void bam_dma_synchronize(struct dma_chan *chan) +{ + vchan_synchronize(&to_bam_chan(chan)->vc); +} + /** * bam_pause - Pause DMA channel * @chan: dma channel @@ -1359,6 +1364,7 @@ static int bam_dma_probe(struct platform_device *pdev) bdev->common.device_pause = bam_pause; bdev->common.device_resume = bam_resume; bdev->common.device_terminate_all = bam_dma_terminate_all; + bdev->common.device_synchronize = bam_dma_synchronize; bdev->common.device_issue_pending = bam_issue_pending; bdev->common.device_tx_status = bam_tx_status; bdev->common.dev = bdev->dev; -- 2.50.1.windows.1