public inbox for dmaengine@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] dmaengine: xilinx: Introduce synchronize() callback
@ 2021-03-13 12:53 Lars-Peter Clausen
  2021-03-16 10:45 ` Vinod Koul
  0 siblings, 1 reply; 2+ messages in thread
From: Lars-Peter Clausen @ 2021-03-13 12:53 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Michal Simek, Radhey Shyam Pandey, Shravya Kumbham, dmaengine,
	Lars-Peter Clausen

The Xilinx dmaengine driver uses a tasklet to process completed
descriptors and execute their callbacks.

Currently consumers of the DMA channel have to no method of synchronization
against this tasklet when using the Xilinx dmaengine drivers. This can lead
to race conditions when the consumer frees resources that are accessed in
the callback before the tasklet has finished running.

It is not enough to just call dmaengine_terminal_all() since on a
multi-processor system the tasklet can run concurrently to it and might
call the callback after dmaengine_terminate_all() has already finished.

To mitigate this issue implement the synchronize() callback for the driver,
which will wait until the tasklet has finished.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/dma/xilinx/xilinx_dma.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 3aded7861fef..75c0b8e904e5 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -2453,6 +2453,13 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
 	return 0;
 }
 
+static void xilinx_dma_synchronize(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	tasklet_kill(&chan->tasklet);
+}
+
 /**
  * xilinx_dma_channel_set_config - Configure VDMA channel
  * Run-time configuration for Axi VDMA, supports:
@@ -3074,6 +3081,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
 	xdev->common.device_free_chan_resources =
 				xilinx_dma_free_chan_resources;
 	xdev->common.device_terminate_all = xilinx_dma_terminate_all;
+	xdev->common.device_synchronize = xilinx_dma_synchronize;
 	xdev->common.device_tx_status = xilinx_dma_tx_status;
 	xdev->common.device_issue_pending = xilinx_dma_issue_pending;
 	if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] dmaengine: xilinx: Introduce synchronize() callback
  2021-03-13 12:53 [PATCH] dmaengine: xilinx: Introduce synchronize() callback Lars-Peter Clausen
@ 2021-03-16 10:45 ` Vinod Koul
  0 siblings, 0 replies; 2+ messages in thread
From: Vinod Koul @ 2021-03-16 10:45 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: Michal Simek, Radhey Shyam Pandey, Shravya Kumbham, dmaengine

On 13-03-21, 13:53, Lars-Peter Clausen wrote:
> The Xilinx dmaengine driver uses a tasklet to process completed
> descriptors and execute their callbacks.
> 
> Currently consumers of the DMA channel have to no method of synchronization
> against this tasklet when using the Xilinx dmaengine drivers. This can lead
> to race conditions when the consumer frees resources that are accessed in
> the callback before the tasklet has finished running.
> 
> It is not enough to just call dmaengine_terminal_all() since on a
> multi-processor system the tasklet can run concurrently to it and might
> call the callback after dmaengine_terminate_all() has already finished.
> 
> To mitigate this issue implement the synchronize() callback for the driver,
> which will wait until the tasklet has finished.

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-03-16 10:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-13 12:53 [PATCH] dmaengine: xilinx: Introduce synchronize() callback Lars-Peter Clausen
2021-03-16 10:45 ` Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox