[PATCH] staging: android: ion: Add requested allocation alignment

Alexey Skidanov alexey.skidanov at intel.com
Mon Feb 12 19:11:40 UTC 2018



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 at intel.com>
>> ---
>>   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
>>
> 


More information about the devel mailing list