From 349e8360c9c85c907147ea2d1d4716468409f2ab Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 14 Aug 2020 22:42:09 +0000 Subject: [PATCH] ANDROID: dma-heap: Rework allocation calls to return struct dma_buf instead of fd While most uses will want to allocate a fd for a dmabuf, there are some cases where it might be useful to have just a dma_buf structure. So refactor the heap allocaiton functions to return a struct dma_buf and add a dma_heap_bufferfd_alloc() function to convert that return a fd. Signed-off-by: John Stultz Change-Id: Id6fd7e8471b9555a08bcdf8ca210feb589fa51c1 Bug: 154341375 --- drivers/dma-buf/dma-heap.c | 44 +++++++++++++++++++++++------ drivers/dma-buf/heaps/cma_heap.c | 21 +++++--------- drivers/dma-buf/heaps/system_heap.c | 21 +++++--------- include/linux/dma-heap.h | 6 ++-- 4 files changed, 52 insertions(+), 40 deletions(-) diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index a64a802003a8..bfc8a7b32486 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -66,26 +66,52 @@ static struct dma_heap *dma_heap_find(const char *name) return NULL; } -static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, - unsigned int fd_flags, - unsigned int heap_flags) +void dma_heap_buffer_free(struct dma_buf *dmabuf) +{ + dma_buf_put(dmabuf); +} + +struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, + unsigned int fd_flags, + unsigned int heap_flags) { if (fd_flags & ~DMA_HEAP_VALID_FD_FLAGS) - return -EINVAL; + return ERR_PTR(-EINVAL); if (heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS) - return -EINVAL; + return ERR_PTR(-EINVAL); /* * Allocations from all heaps have to begin * and end on page boundaries. */ len = PAGE_ALIGN(len); if (!len) - return -EINVAL; + return ERR_PTR(-EINVAL); return heap->ops->allocate(heap, len, fd_flags, heap_flags); } +int dma_heap_bufferfd_alloc(struct dma_heap *heap, size_t len, + unsigned int fd_flags, + unsigned int heap_flags) +{ + struct dma_buf *dmabuf; + int fd; + + dmabuf = dma_heap_buffer_alloc(heap, len, fd_flags, heap_flags); + + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + fd = dma_buf_fd(dmabuf, fd_flags); + if (fd < 0) { + dma_buf_put(dmabuf); + /* just return, as put will call release and that will free */ + } + return fd; + +} + static int dma_heap_open(struct inode *inode, struct file *file) { struct dma_heap *heap; @@ -112,9 +138,9 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data) if (heap_allocation->fd) return -EINVAL; - fd = dma_heap_buffer_alloc(heap, heap_allocation->len, - heap_allocation->fd_flags, - heap_allocation->heap_flags); + fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len, + heap_allocation->fd_flags, + heap_allocation->heap_flags); if (fd < 0) return fd; diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 626cf7fd033a..350b87176f9e 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -40,10 +40,10 @@ static void cma_heap_free(struct heap_helper_buffer *buffer) } /* dmabuf heap CMA operations functions */ -static int cma_heap_allocate(struct dma_heap *heap, - unsigned long len, - unsigned long fd_flags, - unsigned long heap_flags) +struct dma_buf *cma_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) { struct cma_heap *cma_heap = dma_heap_get_drvdata(heap); struct heap_helper_buffer *helper_buffer; @@ -60,7 +60,7 @@ static int cma_heap_allocate(struct dma_heap *heap, helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL); if (!helper_buffer) - return -ENOMEM; + return ERR_PTR(-ENOMEM); init_heap_helper_buffer(helper_buffer, cma_heap_free); helper_buffer->heap = heap; @@ -115,14 +115,7 @@ static int cma_heap_allocate(struct dma_heap *heap, helper_buffer->dmabuf = dmabuf; helper_buffer->priv_virt = cma_pages; - ret = dma_buf_fd(dmabuf, fd_flags); - if (ret < 0) { - dma_buf_put(dmabuf); - /* just return, as put will call release and that will free */ - return ret; - } - - return ret; + return dmabuf; free_pages: kfree(helper_buffer->pages); @@ -130,7 +123,7 @@ free_cma: cma_release(cma_heap->cma, cma_pages, nr_pages); free_buf: kfree(helper_buffer); - return ret; + return ERR_PTR(ret); } static const struct dma_heap_ops cma_heap_ops = { diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 0bf688e3c023..f8f0ab05f70e 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -32,10 +32,10 @@ static void system_heap_free(struct heap_helper_buffer *buffer) kfree(buffer); } -static int system_heap_allocate(struct dma_heap *heap, - unsigned long len, - unsigned long fd_flags, - unsigned long heap_flags) +static struct dma_buf *system_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) { struct heap_helper_buffer *helper_buffer; struct dma_buf *dmabuf; @@ -44,7 +44,7 @@ static int system_heap_allocate(struct dma_heap *heap, helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL); if (!helper_buffer) - return -ENOMEM; + return ERR_PTR(-ENOMEM); init_heap_helper_buffer(helper_buffer, system_heap_free); helper_buffer->heap = heap; @@ -81,14 +81,7 @@ static int system_heap_allocate(struct dma_heap *heap, helper_buffer->dmabuf = dmabuf; - ret = dma_buf_fd(dmabuf, fd_flags); - if (ret < 0) { - dma_buf_put(dmabuf); - /* just return, as put will call release and that will free */ - return ret; - } - - return ret; + return dmabuf; err1: while (pg > 0) @@ -97,7 +90,7 @@ err1: err0: kfree(helper_buffer); - return ret; + return ERR_PTR(ret); } static const struct dma_heap_ops system_heap_ops = { diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h index c1572f29cfac..838e37736ae7 100644 --- a/include/linux/dma-heap.h +++ b/include/linux/dma-heap.h @@ -16,12 +16,12 @@ struct dma_heap; /** * struct dma_heap_ops - ops to operate on a given heap - * @allocate: allocate dmabuf and return fd + * @allocate: allocate dmabuf and return struct dma_buf ptr * - * allocate returns dmabuf fd on success, -errno on error. + * allocate returns dmabuf on success, ERR_PTR(-errno) on error. */ struct dma_heap_ops { - int (*allocate)(struct dma_heap *heap, + struct dma_buf *(*allocate)(struct dma_heap *heap, unsigned long len, unsigned long fd_flags, unsigned long heap_flags);