]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dmaengine: tegra-apb: Prevent race conditions of tasklet vs free list
authorDmitry Osipenko <digetx@gmail.com>
Sun, 9 Feb 2020 16:33:39 +0000 (19:33 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Mar 2020 06:51:18 +0000 (07:51 +0100)
commit c33ee1301c393a241d6424e36eff1071811b1064 upstream.

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 <digetx@gmail.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20200209163356.6439-3-digetx@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/dma/tegra20-apb-dma.c

index f0a6abe2d515b24eb80373265011d36170ec2e05..b5cf5d36de2b49162852546e65b31cec2248185a 100644 (file)
@@ -285,7 +285,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;