[PATCH] staging: android: ion: Add chunk heaps instantiation
Alexey Skidanov
alexey.skidanov at intel.com
Thu Jan 3 06:28:27 UTC 2019
On 1/3/19 12:37 AM, Laura Abbott wrote:
> On 12/20/18 1:29 PM, Alexey Skidanov wrote:
>>
>>
>> On 12/20/18 10:36 PM, Laura Abbott wrote:
>>> On 12/16/18 2:46 AM, Alexey Skidanov wrote:
>>>> Chunk heap instantiation should be supported for device tree platforms
>>>> and
>>>> non device tree platforms. For device tree platforms, it's a platform
>>>> specific code responsibility to retrieve the heap configuration data
>>>> and to call the appropriate API for heap creation. For non device tree
>>>> platforms, there is no defined way to create the heaps.
>>>>
>>>> This patch provides the way of chunk heaps creation using
>>>> "ion_chunk_heap=name:size at start" kernel boot parameter.
>>>>
>>>
>>> I've been thinking about this and I think it works but
>>> I'm still kind of torn about not having devicetree bindings.
>>> It doesn't _preclude_ devicetree bindings but I'd hate to
>>> merge this and then end up with something incompatible.
>>> I do want to support non-Android use cases too.
>> Sorry, what do you mean by non-Android cases?
>
> Any user of Ion that isn't tied to Android. This includes other
> userspace frameworks as well as non-devicetree targets.
>
Sorry, don't follow you ... I tested the patch on Ubuntu machine - so
the non-Android and non-devicetree case is obviously supported :)
>>>
>>> I'm also curious about the value of this heap with just PAGE_SIZE.
>>> The original purpose of the chunk heap was a carveout where
>>> you could easily get allocations large than PAGE_SIZE to
>>> reduce TLB pressure. Do you have another use case for the
>>> chunk heap?
>> It need to be fixed ... Obviously ... The minimum allocation size should
>> be parametrized
>>>
>>> Sumit, do you have any thoughts?
>>>
>>> Thanks,
>>> Laura
>>>
>>>> Link:
>>>> http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-November/128495.html
>>>>
>>>>
>>>> Signed-off-by: Alexey Skidanov <alexey.skidanov at intel.com>
>>>> ---
>>>> drivers/staging/android/ion/ion_chunk_heap.c | 96
>>>> +++++++++++++++++++++++++---
>>>> include/linux/ion.h | 18 ++++++
>>>> 2 files changed, 105 insertions(+), 9 deletions(-)
>>>> create mode 100644 include/linux/ion.h
>>>>
>>>> diff --git a/drivers/staging/android/ion/ion_chunk_heap.c
>>>> b/drivers/staging/android/ion/ion_chunk_heap.c
>>>> index 102c093..1a8e3ad 100644
>>>> --- a/drivers/staging/android/ion/ion_chunk_heap.c
>>>> +++ b/drivers/staging/android/ion/ion_chunk_heap.c
>>>> @@ -21,8 +21,12 @@
>>>> #include <linux/scatterlist.h>
>>>> #include <linux/slab.h>
>>>> #include <linux/vmalloc.h>
>>>> +#include <linux/ion.h>
>>>> #include "ion.h"
>>>> +static struct ion_chunk_heap_cfg
>>>> chunk_heap_cfg[MAX_NUM_OF_CHUNK_HEAPS];
>>>> +static unsigned int num_of_req_chunk_heaps;
>>>> +
>>>> struct ion_chunk_heap {
>>>> struct ion_heap heap;
>>>> struct gen_pool *pool;
>>>> @@ -117,15 +121,15 @@ static struct ion_heap_ops chunk_heap_ops = {
>>>> .unmap_kernel = ion_heap_unmap_kernel,
>>>> };
>>>> -struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap
>>>> *heap_data)
>>>> +static struct ion_heap *ion_chunk_heap_create(struct
>>>> ion_chunk_heap_cfg *heap_cfg)
>>>> {
>>>> struct ion_chunk_heap *chunk_heap;
>>>> int ret;
>>>> struct page *page;
>>>> size_t size;
>>>> - page = pfn_to_page(PFN_DOWN(heap_data->base));
>>>> - size = heap_data->size;
>>>> + page = pfn_to_page(PFN_DOWN(heap_cfg->base));
>>>> + size = heap_cfg->size;
>>>> ret = ion_heap_pages_zero(page, size,
>>>> pgprot_writecombine(PAGE_KERNEL));
>>>> if (ret)
>>>> @@ -135,23 +139,27 @@ struct ion_heap *ion_chunk_heap_create(struct
>>>> ion_platform_heap *heap_data)
>>>> if (!chunk_heap)
>>>> return ERR_PTR(-ENOMEM);
>>>> - chunk_heap->chunk_size = (unsigned long)heap_data->priv;
>>>> + chunk_heap->chunk_size = heap_cfg->chunk_size;
>>>> chunk_heap->pool =
>>>> gen_pool_create(get_order(chunk_heap->chunk_size) +
>>>> PAGE_SHIFT, -1);
>>>> if (!chunk_heap->pool) {
>>>> ret = -ENOMEM;
>>>> goto error_gen_pool_create;
>>>> }
>>>> - chunk_heap->base = heap_data->base;
>>>> - chunk_heap->size = heap_data->size;
>>>> + chunk_heap->base = heap_cfg->base;
>>>> + chunk_heap->size = heap_cfg->size;
>>>> + chunk_heap->heap.name = heap_cfg->heap_name;
>>>> chunk_heap->allocated = 0;
>>>> - gen_pool_add(chunk_heap->pool, chunk_heap->base,
>>>> heap_data->size, -1);
>>>> + gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_cfg->size,
>>>> -1);
>>>> chunk_heap->heap.ops = &chunk_heap_ops;
>>>> chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK;
>>>> chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
>>>> - pr_debug("%s: base %pa size %zu\n", __func__,
>>>> - &chunk_heap->base, heap_data->size);
>>>> +
>>>> + pr_info("%s: name %s base %pa size %zu\n", __func__,
>>>> + heap_cfg->heap_name,
>>>> + &heap_cfg->base,
>>>> + heap_cfg->size);
>>>> return &chunk_heap->heap;
>>>> @@ -160,3 +168,73 @@ struct ion_heap *ion_chunk_heap_create(struct
>>>> ion_platform_heap *heap_data)
>>>> return ERR_PTR(ret);
>>>> }
>>>> +static int __init setup_heap(char *param)
>>>> +{
>>>> + char *at_sign, *coma, *colon;
>>>> + size_t size_to_copy;
>>>> + struct ion_chunk_heap_cfg *cfg;
>>>> +
>>>> + do {
>>>> + cfg = &chunk_heap_cfg[num_of_req_chunk_heaps];
>>>> +
>>>> + /* heap name */
>>>> + colon = strchr(param, ':');
>>>> + if (!colon)
>>>> + return -EINVAL;
>>>> +
>>>> + size_to_copy = min_t(size_t, MAX_CHUNK_HEAP_NAME_SIZE - 1,
>>>> + (colon - param));
>>>> + strncpy(cfg->heap_name, param, size_to_copy);
>>>> + cfg->heap_name[size_to_copy] = '\0';
>>>> +
>>>> + /* heap size */
>>>> + cfg->size = memparse((colon + 1), &at_sign);
>>>> + if ((colon + 1) == at_sign)
>>>> + return -EINVAL;
>>>> +
>>>> + /* heap base addr */
>>>> + if (*at_sign == '@')
>>>> + cfg->base = memparse(at_sign + 1, &coma);
>>>> + else
>>>> + return -EINVAL;
>>>> +
>>>> + if (at_sign == coma)
>>>> + return -EINVAL;
>>>> +
>>>> + /* Chunk size */
>>>> + cfg->chunk_size = PAGE_SIZE;
>>>> +
>>>> + num_of_req_chunk_heaps++;
>>>> +
>>>> + /* if one more heap configuration exists */
>>>> + if (*coma == ',')
>>>> + param = coma + 1;
>>>> + else
>>>> + param = NULL;
>>>> + } while (num_of_req_chunk_heaps < MAX_NUM_OF_CHUNK_HEAPS &&
>>>> param);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +__setup("ion_chunk_heap=", setup_heap);
>>>> +
>>>> +int ion_add_chunk_heaps(struct ion_chunk_heap_cfg *cfg,
>>>> + unsigned int num_of_heaps)
>>>> +{
>>>> + unsigned int i;
>>>> + struct ion_heap *heap;
>>>> +
>>>> + for (i = 0; i < num_of_heaps; i++) {
>>>> + heap = ion_chunk_heap_create(&cfg[i]);
>>>> + if (heap)
>>>> + ion_device_add_heap(heap);
>>>> + }
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int ion_add_chunk_heaps_from_boot_param(void)
>>>> +{
>>>> + return ion_add_chunk_heaps(chunk_heap_cfg,
>>>> num_of_req_chunk_heaps);
>>>> +}
>>>> +
>>>> +device_initcall(ion_add_chunk_heaps_from_boot_param);
>>>> diff --git a/include/linux/ion.h b/include/linux/ion.h
>>>> new file mode 100644
>>>> index 0000000..60296c9
>>>> --- /dev/null
>>>> +++ b/include/linux/ion.h
>>>> @@ -0,0 +1,18 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +#ifndef _LINUX_ION_H
>>>> +#define _LINUX_ION_H
>>>> +
>>>> +#define MAX_NUM_OF_CHUNK_HEAPS 32
>>>> +#define MAX_CHUNK_HEAP_NAME_SIZE 32
>>>> +
>>>> +struct ion_chunk_heap_cfg {
>>>> + char heap_name[MAX_CHUNK_HEAP_NAME_SIZE];
>>>> + phys_addr_t base;
>>>> + size_t size;
>>>> + size_t chunk_size;
>>>> +};
>>>> +
>>>> +int ion_add_chunk_heaps(struct ion_chunk_heap_cfg *cfg,
>>>> + unsigned int num_of_heaps);
>>>> +
>>>> +#endif /* _LINUX_ION_H */
>>>>
>>>
>
More information about the devel
mailing list