[PATCH v4] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
Hongling Zeng
zhongling0719 at 126.com
Tue Jun 30 22:01:08 PDT 2026
在 2026年06月30日 19:34, Vinod Koul 写道:
> On 18-06-26, 10:06, 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.
> Thanks for the patch. Please consider revising the subject which should
> describe the changes in the patch and not the fix/issue.
>
> A better one would be "fix reclaim descriptors while terminating"
Thank you for the suggestion. I'll update the subject in v5 to describe
the changes rather than the issue.
>> 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
>> ---
>> 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
More information about the linux-arm-kernel
mailing list