diff options
| author | Rebecca Schultz Zavin <rebecca@android.com> | 2012-09-10 16:12:01 -0700 |
|---|---|---|
| committer | Arve Hjønnevåg <arve@android.com> | 2013-07-01 14:16:06 -0700 |
| commit | cef82c16097744576bdd2bb5c409ea57d6229f0d (patch) | |
| tree | c7381937abf25184d937ca4515ecfca934dc72fa | |
| parent | b99f7eb334741b72257338ebfc2e447132f178c6 (diff) | |
| download | olio-linux-3.10-cef82c16097744576bdd2bb5c409ea57d6229f0d.tar.xz olio-linux-3.10-cef82c16097744576bdd2bb5c409ea57d6229f0d.zip | |
gpu: ion: Fix memory leak of dirty bits
Change-Id: Ia65ebac1f094bbea4090a5ddfa91bf8f5497bc16
Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com>
| -rw-r--r-- | drivers/gpu/ion/ion.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c index ebb92f6c250..97295de5038 100644 --- a/drivers/gpu/ion/ion.c +++ b/drivers/gpu/ion/ion.c @@ -164,24 +164,20 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, return ERR_PTR(PTR_ERR(table)); } buffer->sg_table = table; - if (buffer->flags & ION_FLAG_CACHED) + if (buffer->flags & ION_FLAG_CACHED) { for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) { if (sg_dma_len(sg) == PAGE_SIZE) continue; pr_err("%s: cached mappings must have pagewise " "sg_lists\n", __func__); - heap->ops->unmap_dma(heap, buffer); - kfree(buffer); - return ERR_PTR(-EINVAL); + ret = -EINVAL; + goto err; } - ret = ion_buffer_alloc_dirty(buffer); - if (ret) { - heap->ops->unmap_dma(heap, buffer); - heap->ops->free(buffer); - kfree(buffer); - return ERR_PTR(ret); + ret = ion_buffer_alloc_dirty(buffer); + if (ret) + goto err; } buffer->dev = dev; @@ -200,6 +196,12 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, sg_dma_address(sg) = sg_phys(sg); ion_buffer_add(dev, buffer); return buffer; + +err: + heap->ops->unmap_dma(heap, buffer); + heap->ops->free(buffer); + kfree(buffer); + return ERR_PTR(ret); } static void ion_buffer_destroy(struct kref *kref) @@ -209,12 +211,13 @@ static void ion_buffer_destroy(struct kref *kref) if (WARN_ON(buffer->kmap_cnt > 0)) buffer->heap->ops->unmap_kernel(buffer->heap, buffer); - buffer->heap->ops->unmap_dma(buffer->heap, buffer); buffer->heap->ops->free(buffer); mutex_lock(&dev->lock); rb_erase(&buffer->node, &dev->buffers); mutex_unlock(&dev->lock); + if (buffer->flags & ION_FLAG_CACHED) + kfree(buffer->dirty); kfree(buffer); } |