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@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? > > 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@xxxxxxxxx> >> --- >> 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 */ >> > _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel