On 02/12/2018 08:42 PM, Laura Abbott wrote: > On 02/10/2018 02:17 AM, Alexey Skidanov wrote: >> Current ion defined allocation ioctl doesn't allow to specify the >> requested >> allocation alignment. CMA heap allocates buffers aligned on buffer size >> page order. >> >> Sometimes, the alignment requirement is less restrictive. In such cases, >> providing specific alignment may reduce the external memory fragmentation >> and in some cases it may avoid the allocation request failure. >> > > I really do not want to bring this back as part of the regular > ABI. Yes, I know it was removed in 4.12. Having an alignment parameter that gets used for exactly > one heap only leads to confusion (which is why it was removed > from the ABI in the first place). You are correct regarding the CMA heap. But, probably it may be used by custom heap as well. > > The alignment came from the behavior of the DMA APIs. Do you > actually need to specify any alignment from userspace or do > you only need page size? Yes. If CMA gives it for free, I would suggest to let the ion user to decide > > Thanks, > Laura > Thanks, Alexey >> To fix this, we add an alignment parameter to the allocation ioctl. >> >> Signed-off-by: Alexey Skidanov <alexey.skidanov@xxxxxxxxx> >> --- >> drivers/staging/android/ion/ion-ioctl.c | 3 ++- >> drivers/staging/android/ion/ion.c | 14 +++++++++----- >> drivers/staging/android/ion/ion.h | 9 ++++++--- >> drivers/staging/android/ion/ion_carveout_heap.c | 3 ++- >> drivers/staging/android/ion/ion_chunk_heap.c | 3 ++- >> drivers/staging/android/ion/ion_cma_heap.c | 18 ++++++++++++------ >> drivers/staging/android/ion/ion_system_heap.c | 6 ++++-- >> drivers/staging/android/uapi/ion.h | 7 +++---- >> 8 files changed, 40 insertions(+), 23 deletions(-) >> >> diff --git a/drivers/staging/android/ion/ion-ioctl.c >> b/drivers/staging/android/ion/ion-ioctl.c >> index c789893..9fe022b 100644 >> --- a/drivers/staging/android/ion/ion-ioctl.c >> +++ b/drivers/staging/android/ion/ion-ioctl.c >> @@ -83,7 +83,8 @@ long ion_ioctl(struct file *filp, unsigned int cmd, >> unsigned long arg) >> fd = ion_alloc(data.allocation.len, >> data.allocation.heap_id_mask, >> - data.allocation.flags); >> + data.allocation.flags, >> + data.allocation.align); >> if (fd < 0) >> return fd; >> diff --git a/drivers/staging/android/ion/ion.c >> b/drivers/staging/android/ion/ion.c >> index f480885..35ddc7a 100644 >> --- a/drivers/staging/android/ion/ion.c >> +++ b/drivers/staging/android/ion/ion.c >> @@ -78,7 +78,8 @@ static void ion_buffer_add(struct ion_device *dev, >> static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, >> struct ion_device *dev, >> unsigned long len, >> - unsigned long flags) >> + unsigned long flags, >> + unsigned int align) >> { >> struct ion_buffer *buffer; >> int ret; >> @@ -90,14 +91,14 @@ static struct ion_buffer *ion_buffer_create(struct >> ion_heap *heap, >> buffer->heap = heap; >> buffer->flags = flags; >> - ret = heap->ops->allocate(heap, buffer, len, flags); >> + ret = heap->ops->allocate(heap, buffer, len, flags, align); >> if (ret) { >> if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) >> goto err2; >> ion_heap_freelist_drain(heap, 0); >> - ret = heap->ops->allocate(heap, buffer, len, flags); >> + ret = heap->ops->allocate(heap, buffer, len, flags, align); >> if (ret) >> goto err2; >> } >> @@ -390,7 +391,10 @@ static const struct dma_buf_ops dma_buf_ops = { >> .unmap = ion_dma_buf_kunmap, >> }; >> -int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int >> flags) >> +int ion_alloc(size_t len, >> + unsigned int heap_id_mask, >> + unsigned int flags, >> + unsigned int align) >> { >> struct ion_device *dev = internal_dev; >> struct ion_buffer *buffer = NULL; >> @@ -417,7 +421,7 @@ int ion_alloc(size_t len, unsigned int >> heap_id_mask, unsigned int flags) >> /* if the caller didn't specify this heap id */ >> if (!((1 << heap->id) & heap_id_mask)) >> continue; >> - buffer = ion_buffer_create(heap, dev, len, flags); >> + buffer = ion_buffer_create(heap, dev, len, flags, align); >> if (!IS_ERR(buffer)) >> break; >> } >> diff --git a/drivers/staging/android/ion/ion.h >> b/drivers/staging/android/ion/ion.h >> index f5f9cd6..0c161d2 100644 >> --- a/drivers/staging/android/ion/ion.h >> +++ b/drivers/staging/android/ion/ion.h >> @@ -123,8 +123,10 @@ struct ion_device { >> */ >> struct ion_heap_ops { >> int (*allocate)(struct ion_heap *heap, >> - struct ion_buffer *buffer, unsigned long len, >> - unsigned long flags); >> + struct ion_buffer *buffer, >> + unsigned long len, >> + unsigned long flags, >> + unsigned int align); >> void (*free)(struct ion_buffer *buffer); >> void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer >> *buffer); >> void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer >> *buffer); >> @@ -228,7 +230,8 @@ int ion_heap_pages_zero(struct page *page, size_t >> size, pgprot_t pgprot); >> int ion_alloc(size_t len, >> unsigned int heap_id_mask, >> - unsigned int flags); >> + unsigned int flags, >> + unsigned int align); >> /** >> * ion_heap_init_shrinker >> diff --git a/drivers/staging/android/ion/ion_carveout_heap.c >> b/drivers/staging/android/ion/ion_carveout_heap.c >> index fee7650..deae9dd 100644 >> --- a/drivers/staging/android/ion/ion_carveout_heap.c >> +++ b/drivers/staging/android/ion/ion_carveout_heap.c >> @@ -59,7 +59,8 @@ static void ion_carveout_free(struct ion_heap *heap, >> phys_addr_t addr, >> static int ion_carveout_heap_allocate(struct ion_heap *heap, >> struct ion_buffer *buffer, >> unsigned long size, >> - unsigned long flags) >> + unsigned long flags, >> + unsigned int align) >> { >> struct sg_table *table; >> phys_addr_t paddr; >> diff --git a/drivers/staging/android/ion/ion_chunk_heap.c >> b/drivers/staging/android/ion/ion_chunk_heap.c >> index 102c093..15f9518 100644 >> --- a/drivers/staging/android/ion/ion_chunk_heap.c >> +++ b/drivers/staging/android/ion/ion_chunk_heap.c >> @@ -35,7 +35,8 @@ struct ion_chunk_heap { >> static int ion_chunk_heap_allocate(struct ion_heap *heap, >> struct ion_buffer *buffer, >> unsigned long size, >> - unsigned long flags) >> + unsigned long flags, >> + unsigned int align) >> { >> struct ion_chunk_heap *chunk_heap = >> container_of(heap, struct ion_chunk_heap, heap); >> diff --git a/drivers/staging/android/ion/ion_cma_heap.c >> b/drivers/staging/android/ion/ion_cma_heap.c >> index 86196ff..f3f8deb 100644 >> --- a/drivers/staging/android/ion/ion_cma_heap.c >> +++ b/drivers/staging/android/ion/ion_cma_heap.c >> @@ -32,25 +32,31 @@ struct ion_cma_heap { >> #define to_cma_heap(x) container_of(x, struct ion_cma_heap, heap) >> /* ION CMA heap operations functions */ >> -static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer >> *buffer, >> +static int ion_cma_allocate(struct ion_heap *heap, >> + struct ion_buffer *buffer, >> unsigned long len, >> - unsigned long flags) >> + unsigned long flags, >> + unsigned int align) >> { >> struct ion_cma_heap *cma_heap = to_cma_heap(heap); >> struct sg_table *table; >> struct page *pages; >> unsigned long size = PAGE_ALIGN(len); >> unsigned long nr_pages = size >> PAGE_SHIFT; >> - unsigned long align = get_order(size); >> + int order = get_order(align); >> int ret; >> - if (align > CONFIG_CMA_ALIGNMENT) >> - align = CONFIG_CMA_ALIGNMENT; >> + /* CMA allocation alignment is in PAGE_SIZE order */ >> + if (order > CONFIG_CMA_ALIGNMENT) >> + order = CONFIG_CMA_ALIGNMENT; >> - pages = cma_alloc(cma_heap->cma, nr_pages, align, GFP_KERNEL); >> + pages = cma_alloc(cma_heap->cma, nr_pages, order, GFP_KERNEL); >> if (!pages) >> return -ENOMEM; >> + pr_debug("Allocated block of %lu pages starting at 0x%lX", >> + nr_pages, page_to_pfn(pages)); >> + >> table = kmalloc(sizeof(*table), GFP_KERNEL); >> if (!table) >> goto err; >> diff --git a/drivers/staging/android/ion/ion_system_heap.c >> b/drivers/staging/android/ion/ion_system_heap.c >> index 4dc5d7a..b5a1720 100644 >> --- a/drivers/staging/android/ion/ion_system_heap.c >> +++ b/drivers/staging/android/ion/ion_system_heap.c >> @@ -125,7 +125,8 @@ static struct page *alloc_largest_available(struct >> ion_system_heap *heap, >> static int ion_system_heap_allocate(struct ion_heap *heap, >> struct ion_buffer *buffer, >> unsigned long size, >> - unsigned long flags) >> + unsigned long flags, >> + unsigned int align) >> { >> struct ion_system_heap *sys_heap = container_of(heap, >> struct ion_system_heap, >> @@ -363,7 +364,8 @@ device_initcall(ion_system_heap_create); >> static int ion_system_contig_heap_allocate(struct ion_heap *heap, >> struct ion_buffer *buffer, >> unsigned long len, >> - unsigned long flags) >> + unsigned long flags, >> + unsigned int align) >> { >> int order = get_order(len); >> struct page *page; >> diff --git a/drivers/staging/android/uapi/ion.h >> b/drivers/staging/android/uapi/ion.h >> index 9e21451..b093edd 100644 >> --- a/drivers/staging/android/uapi/ion.h >> +++ b/drivers/staging/android/uapi/ion.h >> @@ -70,9 +70,8 @@ enum ion_heap_type { >> * @len: size of the allocation >> * @heap_id_mask: mask of heap ids to allocate from >> * @flags: flags passed to heap >> - * @handle: pointer that will be populated with a cookie to >> use to >> - * refer to this allocation >> - * >> + * @fd: file descriptor associated with newly allocated buffer >> + * @align: allocation alignment >> * Provided by userspace as an argument to the ioctl >> */ >> struct ion_allocation_data { >> @@ -80,7 +79,7 @@ struct ion_allocation_data { >> __u32 heap_id_mask; >> __u32 flags; >> __u32 fd; >> - __u32 unused; >> + __u32 align; >> }; >> #define MAX_HEAP_NAME 32 >> > _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel