aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Osipenko <[email protected]>2020-02-09 19:33:39 +0300
committerVinod Koul <[email protected]>2020-02-25 11:57:09 +0530
commitc33ee1301c393a241d6424e36eff1071811b1064 (patch)
tree820e2729f28c84d740298a984bf0e0f65c9e3cf4
parent94788af4ed039476ff3527b0e6a12c1dc42cb022 (diff)
dmaengine: tegra-apb: Prevent race conditions of tasklet vs free list
The interrupt handler puts a half-completed DMA descriptor on a free list and then schedules tasklet to process bottom half of the descriptor that executes client's callback, this creates possibility to pick up the busy descriptor from the free list. Thus, let's disallow descriptor's re-use until it is fully processed. Signed-off-by: Dmitry Osipenko <[email protected]> Acked-by: Jon Hunter <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
-rw-r--r--drivers/dma/tegra20-apb-dma.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 319f31d27014..4a750e29bfb5 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -281,7 +281,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get(
/* Do not allocate if desc are waiting for ack */
list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) {
- if (async_tx_test_ack(&dma_desc->txd)) {
+ if (async_tx_test_ack(&dma_desc->txd) && !dma_desc->cb_count) {
list_del(&dma_desc->node);
spin_unlock_irqrestore(&tdc->lock, flags);
dma_desc->txd.flags = 0;