Re: [PATCH v4] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
From: Frank Li <hidden>
Date: 2026-06-18 03:22:51
Also in:
dmaengine, linux-sunxi, lkml
On Thu, Jun 18, 2026 at 10:06:09AM +0800, Hongling Zeng wrote:
When terminating DMA transfers, active descriptors are not properly
reclaimed. Only cyclic descriptors were handled, leaving non-cyclic
descriptors and their LLI chains to be permanently leaked.
Fix by using vchan_terminate_vdesc() which handles both cyclic and
non-cyclic descriptors by adding them to desc_terminated queue for
proper cleanup.
Add pchan->desc != pchan->done check to prevent double-adding completed
descriptors, which would corrupt the list.
Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Signed-off-by: Hongling Zeng <redacted>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Suggested-by: Frank Li <redacted>Reviewed-by: Frank Li <Frank.Li@nxp.com>
quoted hunk ↗ jump to hunk
--- Change in v2; -Add pchan->desc != pchan->done check to prevent race condition where completed descriptors could be double-added to desc_completed list, causing list corruption --- Change in v3: -Fix by using vchan_terminate_vdesc() as suggested by Frank Li --- Change in v4: -Correct the commit message --- drivers/dma/sun6i-dma.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 7a79f346250a..134ae840f176 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c@@ -946,16 +946,13 @@ static int sun6i_dma_terminate_all(struct dma_chan *chan) spin_lock_irqsave(&vchan->vc.lock, flags); - if (vchan->cyclic) { - vchan->cyclic = false; - if (pchan && pchan->desc) { - struct virt_dma_desc *vd = &pchan->desc->vd; - struct virt_dma_chan *vc = &vchan->vc; - - list_add_tail(&vd->node, &vc->desc_completed); - } + if (pchan && pchan->desc && pchan->desc != pchan->done) { + struct virt_dma_desc *vd = &pchan->desc->vd; + + vchan_terminate_vdesc(vd); } + vchan->cyclic = false; vchan_get_all_descriptors(&vchan->vc, &head); if (pchan) { --2.25.1