From ef878199679b3df661a8551fba19441eee0155a2 Mon Sep 17 00:00:00 2001 From: Sandeep Patil Date: Thu, 8 Aug 2019 08:50:56 -0700 Subject: [PATCH] staging: ion: split system and system-contig heaps This will allows us to build and load them both as individual kernel modules. Bug: 133508579 Test: ion-unit-tests Change-Id: I8bdada5531fbf148e4d097e94e406a232874913a Signed-off-by: Sandeep Patil --- arch/arm64/configs/gki_defconfig | 2 + arch/x86/configs/gki_defconfig | 2 + drivers/staging/android/ion/heaps/Kconfig | 8 ++ drivers/staging/android/ion/heaps/Makefile | 1 + .../ion/heaps/ion_system_contig_heap.c | 111 ++++++++++++++++++ .../android/ion/heaps/ion_system_heap.c | 95 --------------- 6 files changed, 124 insertions(+), 95 deletions(-) create mode 100644 drivers/staging/android/ion/heaps/ion_system_contig_heap.c diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 539f42574383..73acbe383203 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -349,6 +349,8 @@ CONFIG_STAGING=y CONFIG_ASHMEM=y CONFIG_ANDROID_VSOC=y CONFIG_ION=y +CONFIG_ION_SYSTEM_HEAP=y +CONFIG_ION_SYSTEM_CONTIG_HEAP=y CONFIG_COMMON_CLK_SCPI=y CONFIG_HWSPINLOCK=y CONFIG_MAILBOX=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 2d5f55d7b966..ae3d165a79c3 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -289,6 +289,8 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_STAGING=y CONFIG_ASHMEM=y CONFIG_ION=y +CONFIG_ION_SYSTEM_HEAP=y +CONFIG_ION_SYSTEM_CONTIG_HEAP=y CONFIG_PM_DEVFREQ=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig index 7affa91ecabb..f1c7a6b79c01 100644 --- a/drivers/staging/android/ion/heaps/Kconfig +++ b/drivers/staging/android/ion/heaps/Kconfig @@ -6,6 +6,14 @@ config ION_SYSTEM_HEAP Choose this option to enable the Ion system heap. The system heap is backed by pages from the buddy allocator. If in doubt, say Y. +config ION_SYSTEM_CONTIG_HEAP + bool "Ion system contig heap" + depends on ION + help + Choose this option to enable Ion system contig heap. The system contig heap + is backed by the pages from buddy allocator that are guaranteed to be physically + contiguous. If in doubt, say Y. + config ION_CMA_HEAP bool "Ion CMA heap support" depends on ION && DMA_CMA diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile index 127912629f0b..e2ee931100d0 100644 --- a/drivers/staging/android/ion/heaps/Makefile +++ b/drivers/staging/android/ion/heaps/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o +obj-$(CONFIG_ION_SYSTEM_CONTIG_HEAP) += ion_system_contig_heap.o obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o diff --git a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c new file mode 100644 index 000000000000..3a07ef931c2e --- /dev/null +++ b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ION Memory Allocator system contig heap exporter + * + * Copyright (C) 2019 Google, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int ion_system_contig_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long len, + unsigned long flags) +{ + int order = get_order(len); + struct page *page; + struct sg_table *table; + unsigned long i; + int ret; + + page = alloc_pages(GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN, order); + if (!page) + return -ENOMEM; + + split_page(page, order); + + len = PAGE_ALIGN(len); + for (i = len >> PAGE_SHIFT; i < (1 << order); i++) + __free_page(page + i); + + table = kmalloc(sizeof(*table), GFP_KERNEL); + if (!table) { + ret = -ENOMEM; + goto free_pages; + } + + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto free_table; + + sg_set_page(table->sgl, page, len, 0); + + buffer->sg_table = table; + + return 0; + +free_table: + kfree(table); +free_pages: + for (i = 0; i < len >> PAGE_SHIFT; i++) + __free_page(page + i); + + return ret; +} + +static void ion_system_contig_heap_free(struct ion_buffer *buffer) +{ + struct sg_table *table = buffer->sg_table; + struct page *page = sg_page(table->sgl); + unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; + unsigned long i; + + for (i = 0; i < pages; i++) + __free_page(page + i); + sg_free_table(table); + kfree(table); +} + +static struct ion_heap_ops kmalloc_ops = { + .allocate = ion_system_contig_heap_allocate, + .free = ion_system_contig_heap_free, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, + .map_user = ion_heap_map_user, +}; + +static struct ion_heap *__ion_system_contig_heap_create(void) +{ + struct ion_heap *heap; + + heap = kzalloc(sizeof(*heap), GFP_KERNEL); + if (!heap) + return ERR_PTR(-ENOMEM); + heap->ops = &kmalloc_ops; + heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; + heap->name = "ion_system_contig_heap"; + + return heap; +} + +static int ion_system_contig_heap_create(void) +{ + struct ion_heap *heap; + + heap = __ion_system_contig_heap_create(); + if (IS_ERR(heap)) + return PTR_ERR(heap); + + ion_device_add_heap(heap); + + return 0; +} +device_initcall(ion_system_contig_heap_create); + diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c index 3d072dd015ba..df4f5010fa82 100644 --- a/drivers/staging/android/ion/heaps/ion_system_heap.c +++ b/drivers/staging/android/ion/heaps/ion_system_heap.c @@ -281,98 +281,3 @@ static int ion_system_heap_create(void) return 0; } 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) -{ - int order = get_order(len); - struct page *page; - struct sg_table *table; - unsigned long i; - int ret; - - page = alloc_pages(low_order_gfp_flags | __GFP_NOWARN, order); - if (!page) - return -ENOMEM; - - split_page(page, order); - - len = PAGE_ALIGN(len); - for (i = len >> PAGE_SHIFT; i < (1 << order); i++) - __free_page(page + i); - - table = kmalloc(sizeof(*table), GFP_KERNEL); - if (!table) { - ret = -ENOMEM; - goto free_pages; - } - - ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) - goto free_table; - - sg_set_page(table->sgl, page, len, 0); - - buffer->sg_table = table; - - return 0; - -free_table: - kfree(table); -free_pages: - for (i = 0; i < len >> PAGE_SHIFT; i++) - __free_page(page + i); - - return ret; -} - -static void ion_system_contig_heap_free(struct ion_buffer *buffer) -{ - struct sg_table *table = buffer->sg_table; - struct page *page = sg_page(table->sgl); - unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; - unsigned long i; - - for (i = 0; i < pages; i++) - __free_page(page + i); - sg_free_table(table); - kfree(table); -} - -static struct ion_heap_ops kmalloc_ops = { - .allocate = ion_system_contig_heap_allocate, - .free = ion_system_contig_heap_free, - .map_kernel = ion_heap_map_kernel, - .unmap_kernel = ion_heap_unmap_kernel, - .map_user = ion_heap_map_user, -}; - -static struct ion_heap *__ion_system_contig_heap_create(void) -{ - struct ion_heap *heap; - - heap = kzalloc(sizeof(*heap), GFP_KERNEL); - if (!heap) - return ERR_PTR(-ENOMEM); - heap->ops = &kmalloc_ops; - heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; - heap->name = "ion_system_contig_heap"; - - return heap; -} - -static int ion_system_contig_heap_create(void) -{ - struct ion_heap *heap; - - heap = __ion_system_contig_heap_create(); - if (IS_ERR(heap)) - return PTR_ERR(heap); - - ion_device_add_heap(heap); - - return 0; -} -device_initcall(ion_system_contig_heap_create);