summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRebecca Schultz Zavin <rebecca@android.com>2012-09-10 16:12:01 -0700
committerArve Hjønnevåg <arve@android.com>2013-07-01 14:16:06 -0700
commitcef82c16097744576bdd2bb5c409ea57d6229f0d (patch)
treec7381937abf25184d937ca4515ecfca934dc72fa
parentb99f7eb334741b72257338ebfc2e447132f178c6 (diff)
downloadolio-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.c25
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);
}