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: Sumit Semwal <sumit.sem...@linaro.org> Cc: Liam Mark <lm...@codeaurora.org> Cc: Chris Goldsworthy <cgold...@codeaurora.org> Cc: Laura Abbott <labb...@kernel.org> Cc: Brian Starkey <brian.star...@arm.com> Cc: Hridya Valsaraju <hri...@google.com> Cc: Suren Baghdasaryan <sur...@google.com> Cc: Sandeep Patil <sspa...@google.com> Cc: Daniel Mentz <danielme...@google.com> Cc: Ørjan Eide <orjan.e...@arm.com> Cc: Robin Murphy <robin.mur...@arm.com> Cc: Ezequiel Garcia <ezequ...@collabora.com> Cc: Simon Ser <cont...@emersion.fr> Cc: James Jones <jajo...@nvidia.com> Cc: linux-me...@vger.kernel.org Cc: dri-de...@lists.freedesktop.org Signed-off-by: John Stultz <john.stu...@linaro.org> --- drivers/dma-buf/heaps/Kconfig | 1 + drivers/dma-buf/heaps/system_heap.c | 30 ++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index fa5e1c330cce..3c1cdecca9e2 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -5,6 +5,7 @@ config DMABUF_HEAPS_SYSTEM bool "DMA-BUF System Heap" depends on DMABUF_HEAPS select 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. diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 885e30894b77..905b304ea24b 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -22,6 +22,8 @@ #include <linux/vmalloc.h> #include <net/page_pool.h> +#include "deferred-free-helper.h" + static struct dma_heap *sys_heap; struct system_heap_buffer { @@ -32,6 +34,7 @@ struct system_heap_buffer { struct sg_table sg_table; int vmap_cnt; void *vaddr; + struct deferred_freelist_item deferred_free; }; struct dma_heap_attachment { @@ -317,30 +320,43 @@ 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, bool skip_pool) { - struct system_heap_buffer *buffer = dmabuf->priv; + struct system_heap_buffer *buffer = container_of(item, struct system_heap_buffer, deferred_free); struct sg_table *table; struct scatterlist *sg; int i, j; /* Zero the buffer pages before adding back to the pool */ - system_heap_zero_buffer(buffer); + if (!skip_pool) + if (system_heap_zero_buffer(buffer)) + skip_pool = true; // On zeroing 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 (skip_pool) { + __free_pages(page, compound_order(page)); + } else { + for (j = 0; j < NUM_ORDERS; j++) { + if (compound_order(page) == orders[j]) + break; + } + page_pool_put_full_page(pools[j], page, false); } - page_pool_put_full_page(pools[j], page, false); } sg_free_table(table); kfree(buffer); } +static void system_heap_dma_buf_release(struct dma_buf *dmabuf) +{ + struct system_heap_buffer *buffer = dmabuf->priv; + + deferred_free(&buffer->deferred_free, system_heap_buf_free, buffer->len); +} + static const struct dma_buf_ops system_heap_buf_ops = { .attach = system_heap_attach, .detach = system_heap_detach, -- 2.17.1