Skip to content

Commit

Permalink
fsldma: fix memory leak on error path in fsl_dma_prep_memcpy()
Browse files Browse the repository at this point in the history
When preparing a memcpy operation, if the kernel fails to allocate memory
for a link descriptor after the first link descriptor has already been
allocated, then some memory will never be released. Fix the problem by
walking the list of allocated descriptors backwards, and freeing the
allocated descriptors back into the DMA pool.

Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
Signed-off-by: Li Yang <leoli@freescale.com>
  • Loading branch information
Ira Snyder authored and Li Yang committed May 22, 2009
1 parent 776c894 commit 2e077f8
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions drivers/dma/fsldma.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,8 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
{
struct fsl_dma_chan *fsl_chan;
struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
struct list_head *list;
size_t copy;
LIST_HEAD(link_chain);

if (!chan)
return NULL;
Expand All @@ -480,7 +480,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
if (!new) {
dev_err(fsl_chan->dev,
"No free memory for link descriptor\n");
return NULL;
goto fail;
}
#ifdef FSL_DMA_LD_DEBUG
dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
Expand Down Expand Up @@ -515,7 +515,19 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
/* Set End-of-link to the last link descriptor of new list*/
set_ld_eol(fsl_chan, new);

return first ? &first->async_tx : NULL;
return &first->async_tx;

fail:
if (!first)
return NULL;

list = &first->async_tx.tx_list;
list_for_each_entry_safe_reverse(new, prev, list, node) {
list_del(&new->node);
dma_pool_free(fsl_chan->desc_pool, new, new->async_tx.phys);
}

return NULL;
}

/**
Expand Down

0 comments on commit 2e077f8

Please sign in to comment.