Skip to content

Commit

Permalink
dmaengine/ste_dma40: fix memory leak due to prepared descriptors
Browse files Browse the repository at this point in the history
Prepared descriptors that are not submitted will not be freed. Add
prepared descriptor to a list to be able to release them upon
dmaengine_terminate_all().

Signed-off-by: Per Forlin <per.forlin@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
  • Loading branch information
Per Forlin authored and Vinod Koul committed Sep 5, 2011
1 parent 7404368 commit 82babbb
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions drivers/dma/ste_dma40.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ struct d40_base;
* @pending_queue: Submitted jobs, to be issued by issue_pending()
* @active: Active descriptor.
* @queue: Queued jobs.
* @prepare_queue: Prepared jobs.
* @dma_cfg: The client configuration of this dma channel.
* @configured: whether the dma_cfg configuration is valid
* @base: Pointer to the device instance struct.
Expand Down Expand Up @@ -204,6 +205,7 @@ struct d40_chan {
struct list_head pending_queue;
struct list_head active;
struct list_head queue;
struct list_head prepare_queue;
struct stedma40_chan_cfg dma_cfg;
bool configured;
struct d40_base *base;
Expand Down Expand Up @@ -833,6 +835,13 @@ static void d40_term_all(struct d40_chan *d40c)
d40_desc_free(d40c, d40d);
}

/* Release descriptors in prepare queue */
if (!list_empty(&d40c->prepare_queue))
list_for_each_entry_safe(d40d, _d,
&d40c->prepare_queue, node) {
d40_desc_remove(d40d);
d40_desc_free(d40c, d40d);
}

d40c->pending_tx = 0;
d40c->busy = false;
Expand Down Expand Up @@ -1911,6 +1920,12 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,
goto err;
}

/*
* add descriptor to the prepare queue in order to be able
* to free them later in terminate_all
*/
list_add_tail(&desc->node, &chan->prepare_queue);

spin_unlock_irqrestore(&chan->lock, flags);

return &desc->txd;
Expand Down Expand Up @@ -2400,6 +2415,7 @@ static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma,
INIT_LIST_HEAD(&d40c->queue);
INIT_LIST_HEAD(&d40c->pending_queue);
INIT_LIST_HEAD(&d40c->client);
INIT_LIST_HEAD(&d40c->prepare_queue);

tasklet_init(&d40c->tasklet, dma_tasklet,
(unsigned long) d40c);
Expand Down

0 comments on commit 82babbb

Please sign in to comment.