[PATCH v3] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
Hongling Zeng
zenghongling at kylinos.cn
Tue Jun 16 19:34:11 PDT 2026
When terminating a non-cyclic DMA transfer, the active descriptor
is not properly reclaimed. The descriptor is removed from the
desc_issued list in sun6i_dma_start_desc(), but in
sun6i_dma_terminate_all(), only cyclic transfer descriptors are
added to the desc_completed list before cleanup.
For non-cyclic transfers, pchan->desc is set to NULL without first
adding the descriptor back to a list that vchan_get_all_descriptors()
can collect. This causes the descriptor and its associated LLI chain
to be permanently leaked.
Fix by ensuring both cyclic and non-cyclic active descriptors are
added to the desc_completed list before setting pchan->desc to NULL.
Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Signed-off-by: Hongling Zeng <zenghongling at kylinos.cn>
Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Suggested-by: Frank Li <Frank.li at oss.nxp.com>
---
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
---
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
More information about the linux-arm-kernel
mailing list