]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dmaengine: at_hdmac: Free the memset buf without holding the chan lock
authorTudor Ambarus <tudor.ambarus@microchip.com>
Tue, 25 Oct 2022 09:02:43 +0000 (12:02 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Nov 2022 08:57:19 +0000 (09:57 +0100)
commit 6ba826cbb57d675f447b59323204d1473bbd5593 upstream.

There's no need to hold the channel lock when freeing the memset buf, as
the operation has already completed. Free the memset buf without holding
the channel lock.

Fixes: 4d112426c344 ("dmaengine: hdmac: Add memset capabilities")
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Cc: stable@vger.kernel.org
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Link: https://lore.kernel.org/r/20221025090306.297886-1-tudor.ambarus@microchip.com
Link: https://lore.kernel.org/r/20221025090306.297886-10-tudor.ambarus@microchip.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/dma/at_hdmac.c

index 01dfc8dbfc83bc285c23a6f3f57d2a5598e90873..61e1c555cede47b533bd400c43a8d7d0a0dff628 100644 (file)
@@ -443,13 +443,6 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
        if (!atc_chan_is_cyclic(atchan))
                dma_cookie_complete(txd);
 
-       /* If the transfer was a memset, free our temporary buffer */
-       if (desc->memset_buffer) {
-               dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
-                             desc->memset_paddr);
-               desc->memset_buffer = false;
-       }
-
        /* Remove transfer node from the active list. */
        list_del_init(&desc->desc_node);
        spin_unlock_irqrestore(&atchan->lock, flags);
@@ -468,6 +461,13 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
        /* add myself to free_list */
        list_add(&desc->desc_node, &atchan->free_list);
        spin_unlock_irqrestore(&atchan->lock, flags);
+
+       /* If the transfer was a memset, free our temporary buffer */
+       if (desc->memset_buffer) {
+               dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
+                             desc->memset_paddr);
+               desc->memset_buffer = false;
+       }
 }
 
 /**