From: Rebecca Schultz Zavin Date: Mon, 10 Sep 2012 23:12:01 +0000 (-0700) Subject: gpu: ion: Fix memory leak of dirty bits X-Git-Tag: firefly_0821_release~4090^2~678 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cef82c16097744576bdd2bb5c409ea57d6229f0d;p=firefly-linux-kernel-4.4.55.git gpu: ion: Fix memory leak of dirty bits Change-Id: Ia65ebac1f094bbea4090a5ddfa91bf8f5497bc16 Signed-off-by: Rebecca Schultz Zavin --- diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c index ebb92f6c2500..97295de50385 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); }