From: Rebecca Schultz Zavin Date: Fri, 13 Dec 2013 22:24:04 +0000 (-0800) Subject: gpu: ion: Fix memory leak of dirty bits X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=d3c0bced267a6726a2abc44c3457495bd7b427ca;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git gpu: ion: Fix memory leak of dirty bits Signed-off-by: Rebecca Schultz Zavin [jstultz: modified patch to apply to staging directory] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 6ba2c39f793b..3aeb41c258d0 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/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); }