ANDROID: dma-buf: system_heap: Add deferred freeing to the system heap

Utilize the deferred free helper library in the system heap.

This provides a nice performance bump and puts the
system heap performance on par with ION.

Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Liam Mark <lmark@codeaurora.org>
Cc: Chris Goldsworthy <cgoldswo@codeaurora.org>
Cc: Laura Abbott <labbott@kernel.org>
Cc: Brian Starkey <Brian.Starkey@arm.com>
Cc: Hridya Valsaraju <hridya@google.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Sandeep Patil <sspatil@google.com>
Cc: Daniel Mentz <danielmentz@google.com>
Cc: Ørjan Eide <orjan.eide@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Ezequiel Garcia <ezequiel@collabora.com>
Cc: Simon Ser <contact@emersion.fr>
Cc: James Jones <jajones@nvidia.com>
Cc: linux-media@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz <john.stultz@linaro.org>
Bug: 168742043
Change-Id: I720051c84f7fc459f63de8690731f959f7b404e6
---
v2:
* Rework deferred-free api to use reason enum as suggested by
  Suren Baghdasaryan
This commit is contained in:
John Stultz 2020-12-09 05:07:00 +00:00 committed by Hridya Valsaraju
parent 23762f02e1
commit 5438199e35
2 changed files with 26 additions and 7 deletions

View File

@ -8,6 +8,7 @@ config DMABUF_HEAPS_SYSTEM
tristate "DMA-BUF System Heap"
depends on DMABUF_HEAPS
select DMABUF_HEAPS_PAGE_POOL
select DMABUF_HEAPS_DEFERRED_FREE
help
Choose this option to enable the system dmabuf heap. The system heap
is backed by pages from the buddy allocator. If in doubt, say Y.

View File

@ -22,6 +22,7 @@
#include <linux/vmalloc.h>
#include "page_pool.h"
#include "deferred-free-helper.h"
static struct dma_heap *sys_heap;
static struct dma_heap *sys_uncached_heap;
@ -34,6 +35,7 @@ struct system_heap_buffer {
struct sg_table sg_table;
int vmap_cnt;
void *vaddr;
struct deferred_freelist_item deferred_free;
bool uncached;
};
@ -320,30 +322,46 @@ static int system_heap_zero_buffer(struct system_heap_buffer *buffer)
return ret;
}
static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
static void system_heap_buf_free(struct deferred_freelist_item *item,
enum df_reason reason)
{
struct system_heap_buffer *buffer = dmabuf->priv;
struct system_heap_buffer *buffer;
struct sg_table *table;
struct scatterlist *sg;
int i, j;
buffer = container_of(item, struct system_heap_buffer, deferred_free);
/* Zero the buffer pages before adding back to the pool */
system_heap_zero_buffer(buffer);
if (reason == DF_NORMAL)
if (system_heap_zero_buffer(buffer))
reason = DF_UNDER_PRESSURE; // On failure, just free
table = &buffer->sg_table;
for_each_sg(table->sgl, sg, table->nents, i) {
struct page *page = sg_page(sg);
for (j = 0; j < NUM_ORDERS; j++) {
if (compound_order(page) == orders[j])
break;
if (reason == DF_UNDER_PRESSURE) {
__free_pages(page, compound_order(page));
} else {
for (j = 0; j < NUM_ORDERS; j++) {
if (compound_order(page) == orders[j])
break;
}
dmabuf_page_pool_free(pools[j], page);
}
dmabuf_page_pool_free(pools[j], page);
}
sg_free_table(table);
kfree(buffer);
}
static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
{
struct system_heap_buffer *buffer = dmabuf->priv;
int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
deferred_free(&buffer->deferred_free, system_heap_buf_free, npages);
}
static const struct dma_buf_ops system_heap_buf_ops = {
.attach = system_heap_attach,
.detach = system_heap_detach,