On 03/23/2015 05:00 PM, Petr Kulhavy wrote: > If edma_terminate_all() was called while a transfer was running (i.e. after > edma_execute() but before edma_callback()) the echan->edesc was not freed. > > This was due to the fact that a running transfer is on none of the > vchan lists: desc_submitted, desc_issued, desc_completed (edma_execute() > removes it from the desc_issued list), so the vchan_dma_desc_free_list() > called at the end of edma_terminate_all() didn't find it and didn't free it. It is another question if it is really correct to remove the the currently running desc from the issued list in edma_execute(). Based on what I have seen some drivers using virt-dma does this while others not. Russel, do you have any advice on this? Will this work for you to fix the leak: diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 7b65633f495e..ea8544481245 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -162,7 +162,6 @@ static void edma_execute(struct edma_chan *echan) echan->edesc = NULL; return; } - list_del(&vdesc->node); echan->edesc = to_edma_desc(&vdesc->tx); } @@ -760,6 +759,7 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data) dev_dbg(dev, "Transfer complete, stopping channel %d\n", ch_num); edesc->residue = 0; edma_stop(echan->ch_num); + list_del(&edesc->vdesc.node); vchan_cookie_complete(&edesc->vdesc); edma_execute(echan); } else { > This bug was found on an AM1808 based hardware (very similar to da850evm, > however using the second MMC/SD controller), where intense operations on the SD > card wasted the device 128MB RAM within a couple of days. > > Signed-off-by: Petr Kulhavy <petr@xxxxxxxxx> > --- > drivers/dma/edma.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c > index 276157f..1465610 100644 > --- a/drivers/dma/edma.c > +++ b/drivers/dma/edma.c > @@ -260,6 +260,14 @@ static int edma_terminate_all(struct dma_chan *chan) > */ > if (echan->edesc) { > int cyclic = echan->edesc->cyclic; > + > + /* > + * free the running request descriptor > + * since it is on none of the vchan lists > + * desc_submitted, desc_issued, desc_completed > + */ > + kfree(echan->edesc); If we do this I would prefer to have: edma_desc_free(&echan->edesc->vdesc); > + > echan->edesc = NULL; > edma_stop(echan->ch_num); > /* Move the cyclic channel back to default queue */ > -- Péter -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html