diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 2d3da62748b4..71dcb182fb8f 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -458,8 +458,6 @@ CONFIG_UIO=y CONFIG_VHOST_VSOCK=y CONFIG_STAGING=y CONFIG_ASHMEM=y -CONFIG_ION=y -CONFIG_ION_SYSTEM_HEAP=y CONFIG_COMMON_CLK_SCPI=y # CONFIG_CLK_SUNXI is not set # CONFIG_SUNXI_CCU is not set diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig index d4845d044a9f..c016008b652d 100644 --- a/arch/arm64/configs/rockpi4_defconfig +++ b/arch/arm64/configs/rockpi4_defconfig @@ -461,9 +461,6 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y 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_RK808=y CONFIG_COMMON_CLK_SCPI=y CONFIG_HWSPINLOCK=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index f6e683839df1..986862d075d2 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -409,8 +409,6 @@ CONFIG_UIO=y CONFIG_VHOST_VSOCK=y CONFIG_STAGING=y CONFIG_ASHMEM=y -CONFIG_ION=y -CONFIG_ION_SYSTEM_HEAP=y CONFIG_REMOTEPROC=y CONFIG_REMOTEPROC_CDEV=y CONFIG_RPMSG_CHAR=y diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 8d8fd5c29349..70498adb1575 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -14,8 +14,6 @@ config ASHMEM It is, in theory, a good memory allocator for low-memory devices, because it can discard shared memory units when under memory pressure. -source "drivers/staging/android/ion/Kconfig" - endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 3b66cd0b0ec5..e9a55a5e6529 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 ccflags-y += -I$(src) # needed for trace events -obj-y += ion/ - obj-$(CONFIG_ASHMEM) += ashmem.o diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig deleted file mode 100644 index 7b7da979991e..000000000000 --- a/drivers/staging/android/ion/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -menuconfig ION - bool "Ion Memory Manager" - depends on HAS_DMA && MMU - select GENERIC_ALLOCATOR - select DMA_SHARED_BUFFER - help - Choose this option to enable the ION Memory Manager, - used by Android to efficiently allocate buffers - from userspace that can be shared between drivers. - If you're not using Android its probably safe to - say N here. - -source "drivers/staging/android/ion/heaps/Kconfig" diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile deleted file mode 100644 index 7f8fd0f537b4..000000000000 --- a/drivers/staging/android/ion/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o -CFLAGS_ion_buffer.o = -I$(src) -obj-y += heaps/ diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig deleted file mode 100644 index 5034c45a397d..000000000000 --- a/drivers/staging/android/ion/heaps/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config ION_SYSTEM_HEAP - tristate "Ion system heap" - depends on ION - help - 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_CMA_HEAP - tristate "Ion CMA heap support" - depends on ION && DMA_CMA - help - Choose this option to enable CMA heaps with Ion. This heap is backed - by the Contiguous Memory Allocator (CMA). If your system has these - regions, you should say Y here. diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile deleted file mode 100644 index 82e36e89e978..000000000000 --- a/drivers/staging/android/ion/heaps/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_sys_heap.o -ion_sys_heap-y := ion_system_heap.o ion_page_pool.o - -obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o diff --git a/drivers/staging/android/ion/heaps/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c deleted file mode 100644 index 6ba7fd84c9ee..000000000000 --- a/drivers/staging/android/ion/heaps/ion_cma_heap.c +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator CMA heap exporter - * - * Copyright (C) Linaro 2012 - * Author: for ST-Ericsson. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct ion_cma_heap { - struct ion_heap heap; - struct cma *cma; -} cma_heaps[MAX_CMA_AREAS]; - -#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, - unsigned long len, - unsigned long flags) -{ - 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 ret; - - if (align > CONFIG_CMA_ALIGNMENT) - align = CONFIG_CMA_ALIGNMENT; - - pages = cma_alloc(cma_heap->cma, nr_pages, align, false); - if (!pages) - return -ENOMEM; - - if (PageHighMem(pages)) { - unsigned long nr_clear_pages = nr_pages; - struct page *page = pages; - - while (nr_clear_pages > 0) { - void *vaddr = kmap_atomic(page); - - memset(vaddr, 0, PAGE_SIZE); - kunmap_atomic(vaddr); - page++; - nr_clear_pages--; - } - } else { - memset(page_address(pages), 0, size); - } - - table = kmalloc(sizeof(*table), GFP_KERNEL); - if (!table) - goto err; - - ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) - goto free_mem; - - sg_set_page(table->sgl, pages, size, 0); - - buffer->priv_virt = pages; - buffer->sg_table = table; - - ion_buffer_prep_noncached(buffer); - - return 0; - -free_mem: - kfree(table); -err: - cma_release(cma_heap->cma, pages, nr_pages); - return -ENOMEM; -} - -static void ion_cma_free(struct ion_buffer *buffer) -{ - struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); - struct page *pages = buffer->priv_virt; - unsigned long nr_pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; - - /* release memory */ - cma_release(cma_heap->cma, pages, nr_pages); - /* release sg table */ - sg_free_table(buffer->sg_table); - kfree(buffer->sg_table); -} - -static struct ion_heap_ops ion_cma_ops = { - .allocate = ion_cma_allocate, - .free = ion_cma_free, -}; - -static int __ion_add_cma_heap(struct cma *cma, void *data) -{ - int *cma_nr = data; - struct ion_cma_heap *cma_heap; - int ret; - - if (*cma_nr >= MAX_CMA_AREAS) - return -EINVAL; - - cma_heap = &cma_heaps[*cma_nr]; - cma_heap->heap.ops = &ion_cma_ops; - cma_heap->heap.type = ION_HEAP_TYPE_DMA; - cma_heap->heap.name = cma_get_name(cma); - - ret = ion_device_add_heap(&cma_heap->heap); - if (ret) - goto out; - - cma_heap->cma = cma; - *cma_nr += 1; -out: - return 0; -} - -static int __init ion_cma_heap_init(void) -{ - int ret; - int nr = 0; - - ret = cma_for_each_area(__ion_add_cma_heap, &nr); - if (ret) { - for (nr = 0; nr < MAX_CMA_AREAS && cma_heaps[nr].cma; nr++) - ion_device_remove_heap(&cma_heaps[nr].heap); - } - - return ret; -} - -static void __exit ion_cma_heap_exit(void) -{ - int nr; - - for (nr = 0; nr < MAX_CMA_AREAS && cma_heaps[nr].cma; nr++) - ion_device_remove_heap(&cma_heaps[nr].heap); -} - -module_init(ion_cma_heap_init); -module_exit(ion_cma_heap_exit); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/android/ion/heaps/ion_page_pool.c b/drivers/staging/android/ion/heaps/ion_page_pool.c deleted file mode 100644 index efd6ce4cc0ad..000000000000 --- a/drivers/staging/android/ion/heaps/ion_page_pool.c +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator page pool helpers - * - * Copyright (C) 2011 Google, Inc. - */ - -#include -#include -#include -#include - -#include "ion_page_pool.h" - -static inline struct page *ion_page_pool_alloc_pages(struct ion_page_pool *pool) -{ - if (fatal_signal_pending(current)) - return NULL; - return alloc_pages(pool->gfp_mask, pool->order); -} - -static void ion_page_pool_free_pages(struct ion_page_pool *pool, - struct page *page) -{ - __free_pages(page, pool->order); -} - -static void ion_page_pool_add(struct ion_page_pool *pool, struct page *page) -{ - mutex_lock(&pool->mutex); - if (PageHighMem(page)) { - list_add_tail(&page->lru, &pool->high_items); - pool->high_count++; - } else { - list_add_tail(&page->lru, &pool->low_items); - pool->low_count++; - } - - mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, - 1 << pool->order); - mutex_unlock(&pool->mutex); -} - -static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high) -{ - struct page *page; - - if (high) { - BUG_ON(!pool->high_count); - page = list_first_entry(&pool->high_items, struct page, lru); - pool->high_count--; - } else { - BUG_ON(!pool->low_count); - page = list_first_entry(&pool->low_items, struct page, lru); - pool->low_count--; - } - - list_del(&page->lru); - mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, - -(1 << pool->order)); - return page; -} - -struct page *ion_page_pool_alloc(struct ion_page_pool *pool) -{ - struct page *page = NULL; - - BUG_ON(!pool); - - mutex_lock(&pool->mutex); - if (pool->high_count) - page = ion_page_pool_remove(pool, true); - else if (pool->low_count) - page = ion_page_pool_remove(pool, false); - mutex_unlock(&pool->mutex); - - if (!page) - page = ion_page_pool_alloc_pages(pool); - - return page; -} -EXPORT_SYMBOL_GPL(ion_page_pool_alloc); - -void ion_page_pool_free(struct ion_page_pool *pool, struct page *page) -{ - BUG_ON(pool->order != compound_order(page)); - - ion_page_pool_add(pool, page); -} -EXPORT_SYMBOL_GPL(ion_page_pool_free); - -static int ion_page_pool_total(struct ion_page_pool *pool, bool high) -{ - int count = pool->low_count; - - if (high) - count += pool->high_count; - - return count << pool->order; -} - -int ion_page_pool_nr_pages(struct ion_page_pool *pool) -{ - int nr_total_pages; - - mutex_lock(&pool->mutex); - nr_total_pages = ion_page_pool_total(pool, true); - mutex_unlock(&pool->mutex); - - return nr_total_pages; -} -EXPORT_SYMBOL_GPL(ion_page_pool_nr_pages); - -int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, - int nr_to_scan) -{ - int freed = 0; - bool high; - - if (current_is_kswapd()) - high = true; - else - high = !!(gfp_mask & __GFP_HIGHMEM); - - if (nr_to_scan == 0) - return ion_page_pool_total(pool, high); - - while (freed < nr_to_scan) { - struct page *page; - - mutex_lock(&pool->mutex); - if (pool->low_count) { - page = ion_page_pool_remove(pool, false); - } else if (high && pool->high_count) { - page = ion_page_pool_remove(pool, true); - } else { - mutex_unlock(&pool->mutex); - break; - } - mutex_unlock(&pool->mutex); - ion_page_pool_free_pages(pool, page); - freed += (1 << pool->order); - } - - return freed; -} -EXPORT_SYMBOL_GPL(ion_page_pool_shrink); - -struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order) -{ - struct ion_page_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL); - - if (!pool) - return NULL; - pool->high_count = 0; - pool->low_count = 0; - INIT_LIST_HEAD(&pool->low_items); - INIT_LIST_HEAD(&pool->high_items); - pool->gfp_mask = gfp_mask | __GFP_COMP; - pool->order = order; - mutex_init(&pool->mutex); - plist_node_init(&pool->list, order); - - return pool; -} -EXPORT_SYMBOL_GPL(ion_page_pool_create); - -void ion_page_pool_destroy(struct ion_page_pool *pool) -{ - kfree(pool); -} -EXPORT_SYMBOL_GPL(ion_page_pool_destroy); diff --git a/drivers/staging/android/ion/heaps/ion_page_pool.h b/drivers/staging/android/ion/heaps/ion_page_pool.h deleted file mode 100644 index 10c79090c7a0..000000000000 --- a/drivers/staging/android/ion/heaps/ion_page_pool.h +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * ION Page Pool kernel interface header - * - * Copyright (C) 2011 Google, Inc. - */ - -#ifndef _ION_PAGE_POOL_H -#define _ION_PAGE_POOL_H - -#include -#include -#include -#include - -/** - * functions for creating and destroying a heap pool -- allows you - * to keep a pool of pre allocated memory to use from your heap. Keeping - * a pool of memory that is ready for dma, ie any cached mapping have been - * invalidated from the cache, provides a significant performance benefit on - * many systems - */ - -/** - * struct ion_page_pool - pagepool struct - * @high_count: number of highmem items in the pool - * @low_count: number of lowmem items in the pool - * @high_items: list of highmem items - * @low_items: list of lowmem items - * @mutex: lock protecting this struct and especially the count - * item list - * @gfp_mask: gfp_mask to use from alloc - * @order: order of pages in the pool - * @list: plist node for list of pools - * - * Allows you to keep a pool of pre allocated pages to use from your heap. - * Keeping a pool of pages that is ready for dma, ie any cached mapping have - * been invalidated from the cache, provides a significant performance benefit - * on many systems - */ -struct ion_page_pool { - int high_count; - int low_count; - struct list_head high_items; - struct list_head low_items; - struct mutex mutex; - gfp_t gfp_mask; - unsigned int order; - struct plist_node list; -}; - -struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); -void ion_page_pool_destroy(struct ion_page_pool *pool); -struct page *ion_page_pool_alloc(struct ion_page_pool *pool); -void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); -int ion_page_pool_nr_pages(struct ion_page_pool *pool); - -/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool - * @pool: the pool - * @gfp_mask: the memory type to reclaim - * @nr_to_scan: number of items to shrink in pages - * - * returns the number of items freed in pages - */ -int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, - int nr_to_scan); -#endif /* _ION_PAGE_POOL_H */ diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c deleted file mode 100644 index fc630492996f..000000000000 --- a/drivers/staging/android/ion/heaps/ion_system_heap.c +++ /dev/null @@ -1,290 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator system heap exporter - * - * Copyright (C) 2011 Google, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ion_page_pool.h" - -#define NUM_ORDERS ARRAY_SIZE(orders) - -static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | - __GFP_NORETRY) & ~__GFP_RECLAIM; -static gfp_t low_order_gfp_flags = GFP_HIGHUSER | __GFP_ZERO; -static const unsigned int orders[] = {8, 4, 0}; - -static int order_to_index(unsigned int order) -{ - int i; - - for (i = 0; i < NUM_ORDERS; i++) - if (order == orders[i]) - return i; - BUG(); - return -1; -} - -static inline unsigned int order_to_size(int order) -{ - return PAGE_SIZE << order; -} - -struct ion_system_heap { - struct ion_heap heap; - struct ion_page_pool *pools[NUM_ORDERS]; -}; - -static struct page *alloc_buffer_page(struct ion_system_heap *heap, - struct ion_buffer *buffer, - unsigned long order) -{ - struct ion_page_pool *pool = heap->pools[order_to_index(order)]; - - return ion_page_pool_alloc(pool); -} - -static void free_buffer_page(struct ion_system_heap *heap, - struct ion_buffer *buffer, struct page *page) -{ - struct ion_page_pool *pool; - unsigned int order = compound_order(page); - - /* go to system */ - if (buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE) { - __free_pages(page, order); - return; - } - - pool = heap->pools[order_to_index(order)]; - - ion_page_pool_free(pool, page); -} - -static struct page *alloc_largest_available(struct ion_system_heap *heap, - struct ion_buffer *buffer, - unsigned long size, - unsigned int max_order) -{ - struct page *page; - int i; - - for (i = 0; i < NUM_ORDERS; i++) { - if (size < order_to_size(orders[i])) - continue; - if (max_order < orders[i]) - continue; - - page = alloc_buffer_page(heap, buffer, orders[i]); - if (!page) - continue; - - return page; - } - - return NULL; -} - -static int ion_system_heap_allocate(struct ion_heap *heap, - struct ion_buffer *buffer, - unsigned long size, - unsigned long flags) -{ - struct ion_system_heap *sys_heap = container_of(heap, - struct ion_system_heap, - heap); - struct sg_table *table; - struct scatterlist *sg; - struct list_head pages; - struct page *page, *tmp_page; - int i = 0; - unsigned long size_remaining = PAGE_ALIGN(size); - unsigned int max_order = orders[0]; - - if (size / PAGE_SIZE > totalram_pages() / 2) - return -ENOMEM; - - INIT_LIST_HEAD(&pages); - while (size_remaining > 0) { - page = alloc_largest_available(sys_heap, buffer, size_remaining, - max_order); - if (!page) - goto free_pages; - list_add_tail(&page->lru, &pages); - size_remaining -= page_size(page); - max_order = compound_order(page); - i++; - } - table = kmalloc(sizeof(*table), GFP_KERNEL); - if (!table) - goto free_pages; - - if (sg_alloc_table(table, i, GFP_KERNEL)) - goto free_table; - - sg = table->sgl; - list_for_each_entry_safe(page, tmp_page, &pages, lru) { - sg_set_page(sg, page, page_size(page), 0); - sg = sg_next(sg); - list_del(&page->lru); - } - - buffer->sg_table = table; - - ion_buffer_prep_noncached(buffer); - - return 0; - -free_table: - kfree(table); -free_pages: - list_for_each_entry_safe(page, tmp_page, &pages, lru) - free_buffer_page(sys_heap, buffer, page); - return -ENOMEM; -} - -static void ion_system_heap_free(struct ion_buffer *buffer) -{ - struct ion_system_heap *sys_heap = container_of(buffer->heap, - struct ion_system_heap, - heap); - struct sg_table *table = buffer->sg_table; - struct scatterlist *sg; - int i; - - /* zero the buffer before goto page pool */ - if (!(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) - ion_buffer_zero(buffer); - - for_each_sgtable_sg(table, sg, i) - free_buffer_page(sys_heap, buffer, sg_page(sg)); - sg_free_table(table); - kfree(table); -} - -static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, - int nr_to_scan) -{ - struct ion_page_pool *pool; - struct ion_system_heap *sys_heap; - int nr_total = 0; - int i, nr_freed; - int only_scan = 0; - - sys_heap = container_of(heap, struct ion_system_heap, heap); - - if (!nr_to_scan) - only_scan = 1; - - for (i = 0; i < NUM_ORDERS; i++) { - pool = sys_heap->pools[i]; - - if (only_scan) { - nr_total += ion_page_pool_shrink(pool, - gfp_mask, - nr_to_scan); - - } else { - nr_freed = ion_page_pool_shrink(pool, - gfp_mask, - nr_to_scan); - nr_to_scan -= nr_freed; - nr_total += nr_freed; - if (nr_to_scan <= 0) - break; - } - } - return nr_total; -} - -static long ion_system_get_pool_size(struct ion_heap *heap) -{ - struct ion_system_heap *sys_heap; - long total_pages = 0; - int i; - - sys_heap = container_of(heap, struct ion_system_heap, heap); - for (i = 0; i < NUM_ORDERS; i++) - total_pages += ion_page_pool_nr_pages(sys_heap->pools[i]); - - return total_pages; -} - -static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) -{ - int i; - - for (i = 0; i < NUM_ORDERS; i++) - if (pools[i]) - ion_page_pool_destroy(pools[i]); -} - -static int ion_system_heap_create_pools(struct ion_page_pool **pools) -{ - int i; - - for (i = 0; i < NUM_ORDERS; i++) { - struct ion_page_pool *pool; - gfp_t gfp_flags = low_order_gfp_flags; - - if (orders[i] > 4) - gfp_flags = high_order_gfp_flags; - - pool = ion_page_pool_create(gfp_flags, orders[i]); - if (!pool) - goto err_create_pool; - pools[i] = pool; - } - - return 0; - -err_create_pool: - ion_system_heap_destroy_pools(pools); - return -ENOMEM; -} - -static struct ion_heap_ops system_heap_ops = { - .allocate = ion_system_heap_allocate, - .free = ion_system_heap_free, - .shrink = ion_system_heap_shrink, - .get_pool_size = ion_system_get_pool_size, -}; - -static struct ion_system_heap system_heap = { - .heap = { - .ops = &system_heap_ops, - .type = ION_HEAP_TYPE_SYSTEM, - .flags = ION_HEAP_FLAG_DEFER_FREE, - .name = "ion_system_heap", - } -}; - -static int __init ion_system_heap_init(void) -{ - int ret = ion_system_heap_create_pools(system_heap.pools); - if (ret) - return ret; - - return ion_device_add_heap(&system_heap.heap); -} - -static void __exit ion_system_heap_exit(void) -{ - ion_device_remove_heap(&system_heap.heap); - ion_system_heap_destroy_pools(system_heap.pools); -} - -module_init(ion_system_heap_init); -module_exit(ion_system_heap_exit); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c deleted file mode 100644 index 268c4610c25a..000000000000 --- a/drivers/staging/android/ion/ion.c +++ /dev/null @@ -1,519 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator - * - * Copyright (C) 2011 Google, Inc. - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ion_private.h" - -#define ION_CURRENT_ABI_VERSION 2 - -static struct ion_device *internal_dev; - -/* Entry into ION allocator for rest of the kernel */ -struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags) -{ - return ion_dmabuf_alloc(internal_dev, len, heap_id_mask, flags); -} -EXPORT_SYMBOL_GPL(ion_alloc); - -int ion_free(struct ion_buffer *buffer) -{ - return ion_buffer_destroy(internal_dev, buffer); -} -EXPORT_SYMBOL_GPL(ion_free); - -static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, - unsigned int flags) -{ - int fd; - struct dma_buf *dmabuf; - - dmabuf = ion_dmabuf_alloc(internal_dev, len, heap_id_mask, flags); - if (IS_ERR(dmabuf)) - return PTR_ERR(dmabuf); - - fd = dma_buf_fd(dmabuf, O_CLOEXEC); - if (fd < 0) - dma_buf_put(dmabuf); - - return fd; -} - -size_t ion_query_heaps_kernel(struct ion_heap_data *hdata, size_t size) -{ - struct ion_device *dev = internal_dev; - size_t i = 0, num_heaps = 0; - struct ion_heap *heap; - - down_read(&dev->lock); - - // If size is 0, return without updating hdata. - if (size == 0) { - num_heaps = dev->heap_cnt; - goto out; - } - - plist_for_each_entry(heap, &dev->heaps, node) { - strncpy(hdata[i].name, heap->name, MAX_HEAP_NAME); - hdata[i].name[MAX_HEAP_NAME - 1] = '\0'; - hdata[i].type = heap->type; - hdata[i].heap_id = heap->id; - - i++; - if (i >= size) - break; - } - - num_heaps = i; -out: - up_read(&dev->lock); - return num_heaps; -} -EXPORT_SYMBOL_GPL(ion_query_heaps_kernel); - -static int ion_query_heaps(struct ion_heap_query *query) -{ - struct ion_device *dev = internal_dev; - struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps); - int ret = -EINVAL, cnt = 0, max_cnt; - struct ion_heap *heap; - struct ion_heap_data hdata; - - memset(&hdata, 0, sizeof(hdata)); - - down_read(&dev->lock); - if (!buffer) { - query->cnt = dev->heap_cnt; - ret = 0; - goto out; - } - - if (query->cnt <= 0) - goto out; - - max_cnt = query->cnt; - - plist_for_each_entry(heap, &dev->heaps, node) { - strncpy(hdata.name, heap->name, MAX_HEAP_NAME); - hdata.name[sizeof(hdata.name) - 1] = '\0'; - hdata.type = heap->type; - hdata.heap_id = heap->id; - - if (copy_to_user(&buffer[cnt], &hdata, sizeof(hdata))) { - ret = -EFAULT; - goto out; - } - - cnt++; - if (cnt >= max_cnt) - break; - } - - query->cnt = cnt; - ret = 0; -out: - up_read(&dev->lock); - return ret; -} - -union ion_ioctl_arg { - struct ion_allocation_data allocation; - struct ion_heap_query query; - u32 ion_abi_version; -}; - -static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) -{ - switch (cmd) { - case ION_IOC_HEAP_QUERY: - if (arg->query.reserved0 || - arg->query.reserved1 || - arg->query.reserved2) - return -EINVAL; - break; - default: - break; - } - - return 0; -} - -static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret = 0; - union ion_ioctl_arg data; - - if (_IOC_SIZE(cmd) > sizeof(data)) - return -EINVAL; - - /* - * The copy_from_user is unconditional here for both read and write - * to do the validate. If there is no write for the ioctl, the - * buffer is cleared - */ - if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) - return -EFAULT; - - ret = validate_ioctl_arg(cmd, &data); - if (ret) { - pr_warn_once("%s: ioctl validate failed\n", __func__); - return ret; - } - - if (!(_IOC_DIR(cmd) & _IOC_WRITE)) - memset(&data, 0, sizeof(data)); - - switch (cmd) { - case ION_IOC_ALLOC: - { - int fd; - - fd = ion_alloc_fd(data.allocation.len, - data.allocation.heap_id_mask, - data.allocation.flags); - if (fd < 0) - return fd; - - data.allocation.fd = fd; - - break; - } - case ION_IOC_HEAP_QUERY: - ret = ion_query_heaps(&data.query); - break; - case ION_IOC_ABI_VERSION: - data.ion_abi_version = ION_CURRENT_ABI_VERSION; - break; - default: - return -ENOTTY; - } - - if (_IOC_DIR(cmd) & _IOC_READ) { - if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) - return -EFAULT; - } - return ret; -} - -static const struct file_operations ion_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = ion_ioctl, - .compat_ioctl = compat_ptr_ioctl, -}; - -static int debug_shrink_set(void *data, u64 val) -{ - struct ion_heap *heap = data; - struct shrink_control sc; - int objs; - - sc.gfp_mask = GFP_HIGHUSER; - sc.nr_to_scan = val; - - if (!val) { - objs = heap->shrinker.count_objects(&heap->shrinker, &sc); - sc.nr_to_scan = objs; - } - - heap->shrinker.scan_objects(&heap->shrinker, &sc); - return 0; -} - -static int debug_shrink_get(void *data, u64 *val) -{ - struct ion_heap *heap = data; - struct shrink_control sc; - int objs; - - sc.gfp_mask = GFP_HIGHUSER; - sc.nr_to_scan = 0; - - objs = heap->shrinker.count_objects(&heap->shrinker, &sc); - *val = objs; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, - debug_shrink_set, "%llu\n"); - -static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) -{ - int id_bit = -EINVAL; - int start_bit = -1, end_bit = -1; - - switch (heap->type) { - case ION_HEAP_TYPE_SYSTEM: - id_bit = __ffs(ION_HEAP_SYSTEM); - break; - case ION_HEAP_TYPE_DMA: - start_bit = __ffs(ION_HEAP_DMA_START); - end_bit = __ffs(ION_HEAP_DMA_END); - break; - case ION_HEAP_TYPE_CUSTOM ... ION_HEAP_TYPE_MAX: - start_bit = __ffs(ION_HEAP_CUSTOM_START); - end_bit = __ffs(ION_HEAP_CUSTOM_END); - break; - default: - return -EINVAL; - } - - /* For carveout, dma & custom heaps, we first let the heaps choose their - * own IDs. This allows the old behaviour of knowing the heap ids - * of these type of heaps in advance in user space. If a heap with - * that ID already exists, it is an error. - * - * If the heap hasn't picked an id by itself, then we assign it - * one. - */ - if (id_bit < 0) { - if (heap->id) { - id_bit = __ffs(heap->id); - if (id_bit < start_bit || id_bit > end_bit) - return -EINVAL; - } else { - id_bit = find_next_zero_bit(dev->heap_ids, end_bit + 1, - start_bit); - if (id_bit > end_bit) - return -ENOSPC; - } - } - - if (test_and_set_bit(id_bit, dev->heap_ids)) - return -EEXIST; - heap->id = id_bit; - dev->heap_cnt++; - - return 0; -} - -int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) -{ - struct ion_device *dev = internal_dev; - int ret; - struct dentry *heap_root; - char debug_name[64]; - - if (!heap || !heap->ops || !heap->ops->allocate || !heap->ops->free) { - pr_err("%s: invalid heap or heap_ops\n", __func__); - ret = -EINVAL; - goto out; - } - - heap->owner = owner; - spin_lock_init(&heap->free_lock); - spin_lock_init(&heap->stat_lock); - heap->free_list_size = 0; - - if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) { - ret = ion_heap_init_deferred_free(heap); - if (ret) - goto out_heap_cleanup; - } - - if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) { - ret = ion_heap_init_shrinker(heap); - if (ret) { - pr_err("%s: Failed to register shrinker\n", __func__); - goto out_heap_cleanup; - } - } - - heap->num_of_buffers = 0; - heap->num_of_alloc_bytes = 0; - heap->alloc_bytes_wm = 0; - - heap_root = debugfs_create_dir(heap->name, dev->debug_root); - debugfs_create_u64("num_of_buffers", - 0444, heap_root, - &heap->num_of_buffers); - debugfs_create_u64("num_of_alloc_bytes", - 0444, - heap_root, - &heap->num_of_alloc_bytes); - debugfs_create_u64("alloc_bytes_wm", - 0444, - heap_root, - &heap->alloc_bytes_wm); - - if (heap->shrinker.count_objects && - heap->shrinker.scan_objects) { - snprintf(debug_name, 64, "%s_shrink", heap->name); - debugfs_create_file(debug_name, - 0644, - heap_root, - heap, - &debug_shrink_fops); - } - - heap->debugfs_dir = heap_root; - down_write(&dev->lock); - ret = ion_assign_heap_id(heap, dev); - if (ret) { - pr_err("%s: Failed to assign heap id for heap type %x\n", - __func__, heap->type); - up_write(&dev->lock); - goto out_debugfs_cleanup; - } - - /* - * use negative heap->id to reverse the priority -- when traversing - * the list later attempt higher id numbers first - */ - plist_node_init(&heap->node, -heap->id); - plist_add(&heap->node, &dev->heaps); - - up_write(&dev->lock); - - return 0; - -out_debugfs_cleanup: - debugfs_remove_recursive(heap->debugfs_dir); -out_heap_cleanup: - ion_heap_cleanup(heap); -out: - return ret; -} -EXPORT_SYMBOL_GPL(__ion_device_add_heap); - -void ion_device_remove_heap(struct ion_heap *heap) -{ - struct ion_device *dev = internal_dev; - - if (!heap) { - pr_err("%s: Invalid argument\n", __func__); - return; - } - - // take semaphore and remove the heap from dev->heap list - down_write(&dev->lock); - /* So no new allocations can happen from this heap */ - plist_del(&heap->node, &dev->heaps); - if (ion_heap_cleanup(heap) != 0) { - pr_warn("%s: failed to cleanup heap (%s)\n", - __func__, heap->name); - } - debugfs_remove_recursive(heap->debugfs_dir); - clear_bit(heap->id, dev->heap_ids); - dev->heap_cnt--; - up_write(&dev->lock); -} -EXPORT_SYMBOL_GPL(ion_device_remove_heap); - -static ssize_t -total_heaps_kb_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%llu\n", - div_u64(ion_get_total_heap_bytes(), 1024)); -} - -static ssize_t -total_pools_kb_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - struct ion_device *dev = internal_dev; - struct ion_heap *heap; - u64 total_pages = 0; - - down_read(&dev->lock); - plist_for_each_entry(heap, &dev->heaps, node) - if (heap->ops->get_pool_size) - total_pages += heap->ops->get_pool_size(heap); - up_read(&dev->lock); - - return sprintf(buf, "%llu\n", total_pages * (PAGE_SIZE / 1024)); -} - -static struct kobj_attribute total_heaps_kb_attr = - __ATTR_RO(total_heaps_kb); - -static struct kobj_attribute total_pools_kb_attr = - __ATTR_RO(total_pools_kb); - -static struct attribute *ion_device_attrs[] = { - &total_heaps_kb_attr.attr, - &total_pools_kb_attr.attr, - NULL, -}; - -ATTRIBUTE_GROUPS(ion_device); - -static int ion_init_sysfs(void) -{ - struct kobject *ion_kobj; - int ret; - - ion_kobj = kobject_create_and_add("ion", kernel_kobj); - if (!ion_kobj) - return -ENOMEM; - - ret = sysfs_create_groups(ion_kobj, ion_device_groups); - if (ret) { - kobject_put(ion_kobj); - return ret; - } - - return 0; -} - -static int ion_device_create(void) -{ - struct ion_device *idev; - int ret; - - idev = kzalloc(sizeof(*idev), GFP_KERNEL); - if (!idev) - return -ENOMEM; - - idev->dev.minor = MISC_DYNAMIC_MINOR; - idev->dev.name = "ion"; - idev->dev.fops = &ion_fops; - idev->dev.parent = NULL; - ret = misc_register(&idev->dev); - if (ret) { - pr_err("ion: failed to register misc device.\n"); - goto err_reg; - } - - ret = ion_init_sysfs(); - if (ret) { - pr_err("ion: failed to add sysfs attributes.\n"); - goto err_sysfs; - } - - idev->debug_root = debugfs_create_dir("ion", NULL); - init_rwsem(&idev->lock); - plist_head_init(&idev->heaps); - internal_dev = idev; - return 0; - -err_sysfs: - misc_deregister(&idev->dev); -err_reg: - kfree(idev); - return ret; -} -subsys_initcall(ion_device_create); diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c deleted file mode 100644 index 9baca1a472b6..000000000000 --- a/drivers/staging/android/ion/ion_buffer.c +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator - buffer interface - * - * Copyright (c) 2019, Google, Inc. - */ - -#include -#include -#include -#include -#include - -#define CREATE_TRACE_POINTS -#include "ion_trace.h" -#include "ion_private.h" - -static atomic_long_t total_heap_bytes; - -static void track_buffer_created(struct ion_buffer *buffer) -{ - long total = atomic_long_add_return(buffer->size, &total_heap_bytes); - - trace_ion_stat(buffer->sg_table, buffer->size, total); -} - -static void track_buffer_destroyed(struct ion_buffer *buffer) -{ - long total = atomic_long_sub_return(buffer->size, &total_heap_bytes); - - trace_ion_stat(buffer->sg_table, -buffer->size, total); -} - -/* this function should only be called while dev->lock is held */ -static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, - struct ion_device *dev, - unsigned long len, - unsigned long flags) -{ - struct ion_buffer *buffer; - int ret; - - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); - if (!buffer) - return ERR_PTR(-ENOMEM); - - buffer->heap = heap; - buffer->flags = flags; - buffer->size = len; - - ret = heap->ops->allocate(heap, buffer, len, flags); - - 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); - if (ret) - goto err2; - } - - if (!buffer->sg_table) { - WARN_ONCE(1, "This heap needs to set the sgtable"); - ret = -EINVAL; - goto err1; - } - - spin_lock(&heap->stat_lock); - heap->num_of_buffers++; - heap->num_of_alloc_bytes += len; - if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) - heap->alloc_bytes_wm = heap->num_of_alloc_bytes; - if (heap->num_of_buffers == 1) { - /* This module reference lasts as long as at least one - * buffer is allocated from the heap. We are protected - * against ion_device_remove_heap() with dev->lock, so we can - * safely assume the module reference is going to* succeed. - */ - __module_get(heap->owner); - } - spin_unlock(&heap->stat_lock); - - INIT_LIST_HEAD(&buffer->attachments); - mutex_init(&buffer->lock); - track_buffer_created(buffer); - return buffer; - -err1: - heap->ops->free(buffer); -err2: - kfree(buffer); - return ERR_PTR(ret); -} - -static int ion_clear_pages(struct page **pages, int num, pgprot_t pgprot) -{ - void *addr = vmap(pages, num, VM_MAP, pgprot); - - if (!addr) - return -ENOMEM; - memset(addr, 0, PAGE_SIZE * num); - vunmap(addr); - - return 0; -} - -static int ion_sglist_zero(struct scatterlist *sgl, unsigned int nents, - pgprot_t pgprot) -{ - int p = 0; - int ret = 0; - struct sg_page_iter piter; - struct page *pages[32]; - - for_each_sg_page(sgl, &piter, nents, 0) { - pages[p++] = sg_page_iter_page(&piter); - if (p == ARRAY_SIZE(pages)) { - ret = ion_clear_pages(pages, p, pgprot); - if (ret) - return ret; - p = 0; - } - } - if (p) - ret = ion_clear_pages(pages, p, pgprot); - - return ret; -} - -struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, - unsigned int heap_id_mask, - unsigned int flags) -{ - struct ion_buffer *buffer = NULL; - struct ion_heap *heap; - - if (!dev || !len) { - return ERR_PTR(-EINVAL); - } - - /* - * traverse the list of heaps available in this system in priority - * order. If the heap type is supported by the client, and matches the - * request of the caller allocate from it. Repeat until allocate has - * succeeded or all heaps have been tried - */ - len = PAGE_ALIGN(len); - if (!len) - return ERR_PTR(-EINVAL); - - down_read(&dev->lock); - plist_for_each_entry(heap, &dev->heaps, node) { - /* 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); - if (!IS_ERR(buffer)) - break; - } - up_read(&dev->lock); - - if (!buffer) - return ERR_PTR(-ENODEV); - - if (IS_ERR(buffer)) - return ERR_CAST(buffer); - - return buffer; -} - -int ion_buffer_zero(struct ion_buffer *buffer) -{ - struct sg_table *table; - pgprot_t pgprot; - - if (!buffer) - return -EINVAL; - - table = buffer->sg_table; - if (buffer->flags & ION_FLAG_CACHED) - pgprot = PAGE_KERNEL; - else - pgprot = pgprot_writecombine(PAGE_KERNEL); - - return ion_sglist_zero(table->sgl, table->nents, pgprot); -} -EXPORT_SYMBOL_GPL(ion_buffer_zero); - -void ion_buffer_prep_noncached(struct ion_buffer *buffer) -{ - struct scatterlist *sg; - struct sg_table *table; - int i; - - if (WARN_ONCE(!buffer || !buffer->sg_table, - "%s needs a buffer and a sg_table", __func__) || - buffer->flags & ION_FLAG_CACHED) - return; - - table = buffer->sg_table; - - for_each_sg(table->sgl, sg, table->orig_nents, i) - arch_dma_prep_coherent(sg_page(sg), sg->length); -} -EXPORT_SYMBOL_GPL(ion_buffer_prep_noncached); - -void ion_buffer_release(struct ion_buffer *buffer) -{ - if (buffer->kmap_cnt > 0) { - pr_warn_once("%s: buffer still mapped in the kernel\n", - __func__); - ion_heap_unmap_kernel(buffer->heap, buffer); - } - buffer->heap->ops->free(buffer); - spin_lock(&buffer->heap->stat_lock); - buffer->heap->num_of_buffers--; - buffer->heap->num_of_alloc_bytes -= buffer->size; - if (buffer->heap->num_of_buffers == 0) - module_put(buffer->heap->owner); - spin_unlock(&buffer->heap->stat_lock); - /* drop reference to the heap module */ - - kfree(buffer); -} - -int ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) -{ - struct ion_heap *heap; - - if (!dev || !buffer) { - pr_warn("%s: invalid argument\n", __func__); - return -EINVAL; - } - - heap = buffer->heap; - track_buffer_destroyed(buffer); - - if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) - ion_heap_freelist_add(heap, buffer); - else - ion_buffer_release(buffer); - - return 0; -} - -void *ion_buffer_kmap_get(struct ion_buffer *buffer) -{ - void *vaddr; - - if (buffer->kmap_cnt) { - buffer->kmap_cnt++; - return buffer->vaddr; - } - vaddr = ion_heap_map_kernel(buffer->heap, buffer); - if (WARN_ONCE(!vaddr, - "heap->ops->map_kernel should return ERR_PTR on error")) - return ERR_PTR(-EINVAL); - if (IS_ERR(vaddr)) - return vaddr; - buffer->vaddr = vaddr; - buffer->kmap_cnt++; - return vaddr; -} - -void ion_buffer_kmap_put(struct ion_buffer *buffer) -{ - buffer->kmap_cnt--; - if (!buffer->kmap_cnt) { - ion_heap_unmap_kernel(buffer->heap, buffer); - buffer->vaddr = NULL; - } -} - -u64 ion_get_total_heap_bytes(void) -{ - return atomic_long_read(&total_heap_bytes); -} diff --git a/drivers/staging/android/ion/ion_dma_buf.c b/drivers/staging/android/ion/ion_dma_buf.c deleted file mode 100644 index b91db8db6b41..000000000000 --- a/drivers/staging/android/ion/ion_dma_buf.c +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator - dmabuf interface - * - * Copyright (c) 2019, Google, Inc. - */ - -#include -#include -#include -#include -#include - -#include "ion_private.h" - -static struct sg_table *dup_sg_table(struct sg_table *table) -{ - struct sg_table *new_table; - int ret, i; - struct scatterlist *sg, *new_sg; - - new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); - if (!new_table) - return ERR_PTR(-ENOMEM); - - ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); - if (ret) { - kfree(new_table); - return ERR_PTR(-ENOMEM); - } - - new_sg = new_table->sgl; - for_each_sg(table->sgl, sg, table->nents, i) { - memcpy(new_sg, sg, sizeof(*sg)); - new_sg->dma_address = 0; - new_sg = sg_next(new_sg); - } - - return new_table; -} - -static void free_duped_table(struct sg_table *table) -{ - sg_free_table(table); - kfree(table); -} - -static int ion_dma_buf_attach(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) -{ - struct ion_dma_buf_attachment *a; - struct sg_table *table; - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - if (heap->buf_ops.attach) - return heap->buf_ops.attach(dmabuf, attachment); - - a = kzalloc(sizeof(*a), GFP_KERNEL); - if (!a) - return -ENOMEM; - - table = dup_sg_table(buffer->sg_table); - if (IS_ERR(table)) { - kfree(a); - return -ENOMEM; - } - - a->table = table; - a->dev = attachment->dev; - INIT_LIST_HEAD(&a->list); - a->mapped = false; - - attachment->priv = a; - - mutex_lock(&buffer->lock); - list_add(&a->list, &buffer->attachments); - mutex_unlock(&buffer->lock); - - return 0; -} - -static void ion_dma_buf_detatch(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) -{ - struct ion_dma_buf_attachment *a = attachment->priv; - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - if (heap->buf_ops.detach) - return heap->buf_ops.detach(dmabuf, attachment); - - mutex_lock(&buffer->lock); - list_del(&a->list); - mutex_unlock(&buffer->lock); - free_duped_table(a->table); - - kfree(a); -} - -static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, - enum dma_data_direction direction) -{ - struct ion_buffer *buffer = attachment->dmabuf->priv; - struct ion_heap *heap = buffer->heap; - struct ion_dma_buf_attachment *a; - struct sg_table *table; - unsigned long attrs = attachment->dma_map_attrs; - - if (heap->buf_ops.map_dma_buf) - return heap->buf_ops.map_dma_buf(attachment, direction); - - a = attachment->priv; - table = a->table; - - if (!(buffer->flags & ION_FLAG_CACHED)) - attrs |= DMA_ATTR_SKIP_CPU_SYNC; - - if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents, - direction, attrs)) - return ERR_PTR(-ENOMEM); - - a->mapped = true; - - return table; -} - -static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, - struct sg_table *table, - enum dma_data_direction direction) -{ - struct ion_buffer *buffer = attachment->dmabuf->priv; - struct ion_heap *heap = buffer->heap; - struct ion_dma_buf_attachment *a = attachment->priv; - unsigned long attrs = attachment->dma_map_attrs; - - if (heap->buf_ops.unmap_dma_buf) - return heap->buf_ops.unmap_dma_buf(attachment, table, - direction); - - a->mapped = false; - - if (!(buffer->flags & ION_FLAG_CACHED)) - attrs |= DMA_ATTR_SKIP_CPU_SYNC; - - dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents, - direction, attrs); -} - -static void ion_dma_buf_release(struct dma_buf *dmabuf) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - if (heap->buf_ops.release) - return heap->buf_ops.release(dmabuf); - - ion_free(buffer); -} - -static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - struct ion_dma_buf_attachment *a; - - if (heap->buf_ops.begin_cpu_access) - return heap->buf_ops.begin_cpu_access(dmabuf, direction); - - mutex_lock(&buffer->lock); - if (!(buffer->flags & ION_FLAG_CACHED)) - goto unlock; - - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; - dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, - direction); - } - -unlock: - mutex_unlock(&buffer->lock); - return 0; -} - -static int -ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, - enum dma_data_direction direction, - unsigned int offset, unsigned int len) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - /* This is done to make sure partial buffer cache flush / invalidate is - * allowed. The implementation may be vendor specific in this case, so - * ion core does not provide a default implementation - */ - if (!heap->buf_ops.begin_cpu_access_partial) - return -EOPNOTSUPP; - - return heap->buf_ops.begin_cpu_access_partial(dmabuf, direction, offset, - len); -} - -static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - struct ion_dma_buf_attachment *a; - - if (heap->buf_ops.end_cpu_access) - return heap->buf_ops.end_cpu_access(dmabuf, direction); - - mutex_lock(&buffer->lock); - if (!(buffer->flags & ION_FLAG_CACHED)) - goto unlock; - - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; - dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, - direction); - } -unlock: - mutex_unlock(&buffer->lock); - - return 0; -} - -static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, - enum dma_data_direction direction, - unsigned int offset, - unsigned int len) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - /* This is done to make sure partial buffer cache flush / invalidate is - * allowed. The implementation may be vendor specific in this case, so - * ion core does not provide a default implementation - */ - if (!heap->buf_ops.end_cpu_access_partial) - return -EOPNOTSUPP; - - return heap->buf_ops.end_cpu_access_partial(dmabuf, direction, offset, - len); -} - -static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - int ret; - - /* now map it to userspace */ - if (heap->buf_ops.mmap) { - ret = heap->buf_ops.mmap(dmabuf, vma); - } else { - mutex_lock(&buffer->lock); - if (!(buffer->flags & ION_FLAG_CACHED)) - vma->vm_page_prot = - pgprot_writecombine(vma->vm_page_prot); - - ret = ion_heap_map_user(heap, buffer, vma); - mutex_unlock(&buffer->lock); - } - - if (ret) - pr_err("%s: failure mapping buffer to userspace\n", __func__); - - return ret; -} - -static int ion_dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - void *vaddr; - - if (heap->buf_ops.vmap) - return heap->buf_ops.vmap(dmabuf, map); - - mutex_lock(&buffer->lock); - vaddr = ion_buffer_kmap_get(buffer); - mutex_unlock(&buffer->lock); - - dma_buf_map_set_vaddr(map, vaddr); - return 0; -} - -static void ion_dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - if (heap->buf_ops.vunmap) { - heap->buf_ops.vunmap(dmabuf, map); - return; - } - - mutex_lock(&buffer->lock); - ion_buffer_kmap_put(buffer); - mutex_unlock(&buffer->lock); -} - -static int ion_dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) -{ - struct ion_buffer *buffer = dmabuf->priv; - struct ion_heap *heap = buffer->heap; - - if (!heap->buf_ops.get_flags) - return -EOPNOTSUPP; - - return heap->buf_ops.get_flags(dmabuf, flags); -} - -static const struct dma_buf_ops dma_buf_ops = { - .attach = ion_dma_buf_attach, - .detach = ion_dma_buf_detatch, - .map_dma_buf = ion_map_dma_buf, - .unmap_dma_buf = ion_unmap_dma_buf, - .release = ion_dma_buf_release, - .begin_cpu_access = ion_dma_buf_begin_cpu_access, - .begin_cpu_access_partial = ion_dma_buf_begin_cpu_access_partial, - .end_cpu_access = ion_dma_buf_end_cpu_access, - .end_cpu_access_partial = ion_dma_buf_end_cpu_access_partial, - .mmap = ion_dma_buf_mmap, - .vmap = ion_dma_buf_vmap, - .vunmap = ion_dma_buf_vunmap, - .get_flags = ion_dma_buf_get_flags, -}; - -struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, - unsigned int heap_id_mask, - unsigned int flags) -{ - struct ion_buffer *buffer; - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - struct dma_buf *dmabuf; - - pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, - len, heap_id_mask, flags); - - buffer = ion_buffer_alloc(dev, len, heap_id_mask, flags); - if (IS_ERR(buffer)) - return ERR_CAST(buffer); - - exp_info.ops = &dma_buf_ops; - exp_info.size = buffer->size; - exp_info.flags = O_RDWR; - exp_info.priv = buffer; - - dmabuf = dma_buf_export(&exp_info); - if (IS_ERR(dmabuf)) - ion_buffer_destroy(dev, buffer); - - return dmabuf; -} diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c deleted file mode 100644 index aa29a4ee48a3..000000000000 --- a/drivers/staging/android/ion/ion_heap.c +++ /dev/null @@ -1,291 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ION Memory Allocator generic heap helpers - * - * Copyright (C) 2011 Google, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ion_private.h" - -static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, - struct shrink_control *sc) -{ - struct ion_heap *heap = container_of(shrinker, struct ion_heap, - shrinker); - int total = 0; - - total = ion_heap_freelist_size(heap) / PAGE_SIZE; - - if (heap->ops->shrink) - total += heap->ops->shrink(heap, sc->gfp_mask, 0); - - return total; -} - -static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, - struct shrink_control *sc) -{ - struct ion_heap *heap = container_of(shrinker, struct ion_heap, - shrinker); - int freed = 0; - int to_scan = sc->nr_to_scan; - - if (to_scan == 0) - return 0; - - /* - * shrink the free list first, no point in zeroing the memory if we're - * just going to reclaim it. Also, skip any possible page pooling. - */ - if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) - freed = ion_heap_freelist_shrink(heap, to_scan * PAGE_SIZE) / - PAGE_SIZE; - - to_scan -= freed; - if (to_scan <= 0) - return freed; - - if (heap->ops->shrink) - freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); - - return freed; -} - -static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, - bool skip_pools) -{ - struct ion_buffer *buffer; - size_t total_drained = 0; - - if (ion_heap_freelist_size(heap) == 0) - return 0; - - spin_lock(&heap->free_lock); - if (size == 0) - size = heap->free_list_size; - - while (!list_empty(&heap->free_list)) { - if (total_drained >= size) - break; - buffer = list_first_entry(&heap->free_list, struct ion_buffer, - list); - list_del(&buffer->list); - heap->free_list_size -= buffer->size; - if (skip_pools) - buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; - total_drained += buffer->size; - spin_unlock(&heap->free_lock); - ion_buffer_release(buffer); - spin_lock(&heap->free_lock); - } - spin_unlock(&heap->free_lock); - - return total_drained; -} - -static int ion_heap_deferred_free(void *data) -{ - struct ion_heap *heap = data; - - while (true) { - struct ion_buffer *buffer; - - wait_event_freezable(heap->waitqueue, - (ion_heap_freelist_size(heap) > 0 || - kthread_should_stop())); - - spin_lock(&heap->free_lock); - if (list_empty(&heap->free_list)) { - spin_unlock(&heap->free_lock); - if (!kthread_should_stop()) - continue; - break; - } - buffer = list_first_entry(&heap->free_list, struct ion_buffer, - list); - list_del(&buffer->list); - heap->free_list_size -= buffer->size; - spin_unlock(&heap->free_lock); - ion_buffer_release(buffer); - } - - return 0; -} - -void *ion_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - struct scatterlist *sg; - int i, j; - void *vaddr; - pgprot_t pgprot; - struct sg_table *table = buffer->sg_table; - int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; - struct page **pages = vmalloc(array_size(npages, - sizeof(struct page *))); - struct page **tmp = pages; - - if (!pages) - return ERR_PTR(-ENOMEM); - - if (buffer->flags & ION_FLAG_CACHED) - pgprot = PAGE_KERNEL; - else - pgprot = pgprot_writecombine(PAGE_KERNEL); - - for_each_sg(table->sgl, sg, table->nents, i) { - int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; - struct page *page = sg_page(sg); - - BUG_ON(i >= npages); - for (j = 0; j < npages_this_entry; j++) - *(tmp++) = page++; - } - vaddr = vmap(pages, npages, VM_MAP, pgprot); - vfree(pages); - - if (!vaddr) - return ERR_PTR(-ENOMEM); - - return vaddr; -} -EXPORT_SYMBOL_GPL(ion_heap_map_kernel); - -void ion_heap_unmap_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - vunmap(buffer->vaddr); -} -EXPORT_SYMBOL_GPL(ion_heap_unmap_kernel); - -int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - struct sg_table *table = buffer->sg_table; - unsigned long addr = vma->vm_start; - unsigned long offset = vma->vm_pgoff * PAGE_SIZE; - struct scatterlist *sg; - int i; - int ret; - - for_each_sg(table->sgl, sg, table->nents, i) { - struct page *page = sg_page(sg); - unsigned long remainder = vma->vm_end - addr; - unsigned long len = sg->length; - - if (offset >= sg->length) { - offset -= sg->length; - continue; - } else if (offset) { - page += offset / PAGE_SIZE; - len = sg->length - offset; - offset = 0; - } - len = min(len, remainder); - ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, - vma->vm_page_prot); - if (ret) - return ret; - addr += len; - if (addr >= vma->vm_end) - return 0; - } - - return 0; -} -EXPORT_SYMBOL_GPL(ion_heap_map_user); - -void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) -{ - spin_lock(&heap->free_lock); - list_add(&buffer->list, &heap->free_list); - heap->free_list_size += buffer->size; - spin_unlock(&heap->free_lock); - wake_up(&heap->waitqueue); -} - -size_t ion_heap_freelist_size(struct ion_heap *heap) -{ - size_t size; - - spin_lock(&heap->free_lock); - size = heap->free_list_size; - spin_unlock(&heap->free_lock); - - return size; -} - -size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) -{ - return _ion_heap_freelist_drain(heap, size, false); -} - -size_t ion_heap_freelist_shrink(struct ion_heap *heap, size_t size) -{ - return _ion_heap_freelist_drain(heap, size, true); -} - -int ion_heap_init_deferred_free(struct ion_heap *heap) -{ - INIT_LIST_HEAD(&heap->free_list); - init_waitqueue_head(&heap->waitqueue); - heap->task = kthread_run(ion_heap_deferred_free, heap, - "%s", heap->name); - if (IS_ERR(heap->task)) { - pr_err("%s: creating thread for deferred free failed\n", - __func__); - return PTR_ERR_OR_ZERO(heap->task); - } - sched_set_normal(heap->task, 19); - - return 0; -} - -int ion_heap_init_shrinker(struct ion_heap *heap) -{ - heap->shrinker.count_objects = ion_heap_shrink_count; - heap->shrinker.scan_objects = ion_heap_shrink_scan; - heap->shrinker.seeks = DEFAULT_SEEKS; - heap->shrinker.batch = 0; - - return register_shrinker(&heap->shrinker); -} - -int ion_heap_cleanup(struct ion_heap *heap) -{ - int ret; - - if (heap->flags & ION_HEAP_FLAG_DEFER_FREE && - !IS_ERR_OR_NULL(heap->task)) { - size_t free_list_size = ion_heap_freelist_size(heap); - size_t total_drained = ion_heap_freelist_drain(heap, 0); - - if (total_drained != free_list_size) { - pr_err("%s: %s heap drained %zu bytes, requested %zu\n", - __func__, heap->name, free_list_size, - total_drained); - return -EBUSY; - } - ret = kthread_stop(heap->task); - if (ret < 0) { - pr_err("%s: failed to stop heap free thread\n", - __func__); - return ret; - } - } - - if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) - unregister_shrinker(&heap->shrinker); - - return 0; -} diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h deleted file mode 100644 index db4e90683f4c..000000000000 --- a/drivers/staging/android/ion/ion_private.h +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * ION Memory Allocator - Internal header - * - * Copyright (C) 2019 Google, Inc. - */ - -#ifndef _ION_PRIVATE_H -#define _ION_PRIVATE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * struct ion_device - the metadata of the ion device node - * @dev: the actual misc device - * @lock: rwsem protecting the tree of heaps, heap_bitmap and - * clients - * @heap_ids: bitmap of register heap ids - */ -struct ion_device { - struct miscdevice dev; - struct rw_semaphore lock; - DECLARE_BITMAP(heap_ids, ION_NUM_MAX_HEAPS); - struct plist_head heaps; - struct dentry *debug_root; - int heap_cnt; -}; - -/* ion_buffer manipulators */ -extern struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, - unsigned int heap_id_mask, - unsigned int flags); -extern void ion_buffer_release(struct ion_buffer *buffer); -extern int ion_buffer_destroy(struct ion_device *dev, - struct ion_buffer *buffer); -extern void *ion_buffer_kmap_get(struct ion_buffer *buffer); -extern void ion_buffer_kmap_put(struct ion_buffer *buffer); - -/* ion dmabuf allocator */ -extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, - unsigned int heap_id_mask, - unsigned int flags); -extern int ion_free(struct ion_buffer *buffer); - -/* ion heap helpers */ -extern int ion_heap_cleanup(struct ion_heap *heap); - -u64 ion_get_total_heap_bytes(void); - -#endif /* _ION_PRIVATE_H */ diff --git a/drivers/staging/android/ion/ion_trace.h b/drivers/staging/android/ion/ion_trace.h deleted file mode 100644 index eacb47d4f135..000000000000 --- a/drivers/staging/android/ion/ion_trace.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * drivers/staging/android/ion/ion-trace.h - * - * Copyright (C) 2020 Google, Inc. - */ - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM ion - -#if !defined(_ION_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -#define _ION_TRACE_H - -#include - -#ifndef __ION_PTR_TO_HASHVAL -static unsigned int __maybe_unused __ion_ptr_to_hash(const void *ptr) -{ - unsigned long hashval; - - if (ptr_to_hashval(ptr, &hashval)) - return 0; - - /* The hashed value is only 32-bit */ - return (unsigned int)hashval; -} - -#define __ION_PTR_TO_HASHVAL -#endif - -TRACE_EVENT(ion_stat, - TP_PROTO(const void *addr, long len, - unsigned long total_allocated), - TP_ARGS(addr, len, total_allocated), - TP_STRUCT__entry(__field(unsigned int, buffer_id) - __field(long, len) - __field(unsigned long, total_allocated) - ), - TP_fast_assign(__entry->buffer_id = __ion_ptr_to_hash(addr); - __entry->len = len; - __entry->total_allocated = total_allocated; - ), - TP_printk("buffer_id=%u len=%ldB total_allocated=%ldB", - __entry->buffer_id, - __entry->len, - __entry->total_allocated) - ); - -#endif /* _ION_TRACE_H */ - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#define TRACE_INCLUDE_FILE ion_trace -#include diff --git a/include/linux/ion.h b/include/linux/ion.h deleted file mode 100644 index 80c6fdeb4822..000000000000 --- a/include/linux/ion.h +++ /dev/null @@ -1,419 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. - */ - -#ifndef _ION_KERNEL_H -#define _ION_KERNEL_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * struct ion_buffer - metadata for a particular buffer - * @list: element in list of deferred freeable buffers - * @heap: back pointer to the heap the buffer came from - * @flags: buffer specific flags - * @private_flags: internal buffer specific flags - * @size: size of the buffer - * @priv_virt: private data to the buffer representable as - * a void * - * @lock: protects the buffers cnt fields - * @kmap_cnt: number of times the buffer is mapped to the kernel - * @vaddr: the kernel mapping if kmap_cnt is not zero - * @sg_table: the sg table for the buffer - * @attachments: list of devices attached to this buffer - */ -struct ion_buffer { - struct list_head list; - struct ion_heap *heap; - unsigned long flags; - unsigned long private_flags; - size_t size; - void *priv_virt; - struct mutex lock; - int kmap_cnt; - void *vaddr; - struct sg_table *sg_table; - struct list_head attachments; -}; - -/** - * struct ion_heap_ops - ops to operate on a given heap - * @allocate: allocate memory - * @free: free memory - * @get_pool_size: get pool size in pages - * - * allocate returns 0 on success, -errno on error. - * map_dma and map_kernel return pointer on success, ERR_PTR on - * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in - * the buffer's private_flags when called from a shrinker. In that - * case, the pages being free'd must be truly free'd back to the - * system, not put in a page pool or otherwise cached. - */ -struct ion_heap_ops { - int (*allocate)(struct ion_heap *heap, - struct ion_buffer *buffer, unsigned long len, - unsigned long flags); - void (*free)(struct ion_buffer *buffer); - int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); - long (*get_pool_size)(struct ion_heap *heap); -}; - -/** - * heap flags - flags between the heaps and core ion code - */ -#define ION_HEAP_FLAG_DEFER_FREE BIT(0) - -/** - * private flags - flags internal to ion - */ -/* - * Buffer is being freed from a shrinker function. Skip any possible - * heap-specific caching mechanism (e.g. page pools). Guarantees that - * any buffer storage that came from the system allocator will be - * returned to the system allocator. - */ -#define ION_PRIV_FLAG_SHRINKER_FREE BIT(0) - -/** - * struct ion_heap - represents a heap in the system - * @node: rb node to put the heap on the device's tree of heaps - * @type: type of heap - * @ops: ops struct as above - * @buf_ops: dma_buf ops specific to the heap implementation. - * @flags: flags - * @id: id of heap, also indicates priority of this heap when - * allocating. These are specified by platform data and - * MUST be unique - * @name: used for debugging - * @owner: kernel module that implements this heap - * @shrinker: a shrinker for the heap - * @free_list: free list head if deferred free is used - * @free_list_size size of the deferred free list in bytes - * @lock: protects the free list - * @waitqueue: queue to wait on from deferred free thread - * @task: task struct of deferred free thread - * @num_of_buffers the number of currently allocated buffers - * @num_of_alloc_bytes the number of allocated bytes - * @alloc_bytes_wm the number of allocated bytes watermark - * - * Represents a pool of memory from which buffers can be made. In some - * systems the only heap is regular system memory allocated via vmalloc. - * On others, some blocks might require large physically contiguous buffers - * that are allocated from a specially reserved heap. - */ -struct ion_heap { - struct plist_node node; - enum ion_heap_type type; - struct ion_heap_ops *ops; - struct dma_buf_ops buf_ops; - unsigned long flags; - unsigned int id; - const char *name; - struct module *owner; - - /* deferred free support */ - struct shrinker shrinker; - struct list_head free_list; - size_t free_list_size; - spinlock_t free_lock; - wait_queue_head_t waitqueue; - struct task_struct *task; - - /* heap statistics */ - u64 num_of_buffers; - u64 num_of_alloc_bytes; - u64 alloc_bytes_wm; - - /* protect heap statistics */ - spinlock_t stat_lock; - - /* heap's debugfs root */ - struct dentry *debugfs_dir; -}; - -#define ion_device_add_heap(heap) __ion_device_add_heap(heap, THIS_MODULE) - -/** - * struct ion_dma_buf_attachment - hold device-table attachment data for buffer - * @dev: device attached to the buffer. - * @table: cached mapping. - * @list: list of ion_dma_buf_attachment. - */ -struct ion_dma_buf_attachment { - struct device *dev; - struct sg_table *table; - struct list_head list; - bool mapped:1; -}; - -#ifdef CONFIG_ION - -/** - * __ion_device_add_heap - adds a heap to the ion device - * - * @heap: the heap to add - * - * Returns 0 on success, negative error otherwise. - */ -int __ion_device_add_heap(struct ion_heap *heap, struct module *owner); - -/** - * ion_device_remove_heap - removes a heap from ion device - * - * @heap: pointer to the heap to be removed - */ -void ion_device_remove_heap(struct ion_heap *heap); - -/** - * ion_heap_init_shrinker - * @heap: the heap - * - * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag or defines the shrink op - * this function will be called to setup a shrinker to shrink the freelists - * and call the heap's shrink op. - */ -int ion_heap_init_shrinker(struct ion_heap *heap); - -/** - * ion_heap_init_deferred_free -- initialize deferred free functionality - * @heap: the heap - * - * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will - * be called to setup deferred frees. Calls to free the buffer will - * return immediately and the actual free will occur some time later - */ -int ion_heap_init_deferred_free(struct ion_heap *heap); - -/** - * ion_heap_freelist_add - add a buffer to the deferred free list - * @heap: the heap - * @buffer: the buffer - * - * Adds an item to the deferred freelist. - */ -void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); - -/** - * ion_heap_freelist_drain - drain the deferred free list - * @heap: the heap - * @size: amount of memory to drain in bytes - * - * Drains the indicated amount of memory from the deferred freelist immediately. - * Returns the total amount freed. The total freed may be higher depending - * on the size of the items in the list, or lower if there is insufficient - * total memory on the freelist. - */ -size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); - -/** - * ion_heap_freelist_shrink - drain the deferred free - * list, skipping any heap-specific - * pooling or caching mechanisms - * - * @heap: the heap - * @size: amount of memory to drain in bytes - * - * Drains the indicated amount of memory from the deferred freelist immediately. - * Returns the total amount freed. The total freed may be higher depending - * on the size of the items in the list, or lower if there is insufficient - * total memory on the freelist. - * - * Unlike with @ion_heap_freelist_drain, don't put any pages back into - * page pools or otherwise cache the pages. Everything must be - * genuinely free'd back to the system. If you're free'ing from a - * shrinker you probably want to use this. Note that this relies on - * the heap.ops.free callback honoring the ION_PRIV_FLAG_SHRINKER_FREE - * flag. - */ -size_t ion_heap_freelist_shrink(struct ion_heap *heap, - size_t size); - -/** - * ion_heap_freelist_size - returns the size of the freelist in bytes - * @heap: the heap - */ -size_t ion_heap_freelist_size(struct ion_heap *heap); - -/** - * ion_heap_map_kernel - map the ion_buffer in kernel virtual address space. - * - * @heap: the heap - * @buffer: buffer to be mapped - * - * Maps the buffer using vmap(). The function respects cache flags for the - * buffer and creates the page table entries accordingly. Returns virtual - * address at the beginning of the buffer or ERR_PTR. - */ -void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); - -/** - * ion_heap_unmap_kernel - unmap ion_buffer - * - * @buffer: buffer to be unmapped - * - * ION wrapper for vunmap() of the ion buffer. - */ -void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); - -/** - * ion_heap_map_user - map given ion buffer in provided vma - * - * @heap: the heap this buffer belongs to - * @buffer: Ion buffer to be mapped - * @vma: vma of the process where buffer should be mapped. - * - * Maps the buffer using remap_pfn_range() into specific process's vma starting - * with vma->vm_start. The vma size is expected to be >= ion buffer size. - * If not, a partial buffer mapping may be created. Returns 0 on success. - */ -int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma); - -/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. - * - * @buffer: ion_buffer to zero - * - * Returns 0 on success, negative error otherwise. - */ -int ion_buffer_zero(struct ion_buffer *buffer); - -/** - * ion_buffer_prep_noncached - flush cache before non-cached mapping - * - * @buffer: ion_buffer to flush - * - * The memory allocated by the heap could be in the CPU cache. To map - * this memory as non-cached, we need to flush the associated cache - * first. Without the flush, it is possible for stale dirty cache lines - * to be evicted after the ION client started writing into this buffer, - * leading to data corruption. - */ -void ion_buffer_prep_noncached(struct ion_buffer *buffer); - -/** - * ion_alloc - Allocates an ion buffer of given size from given heap - * - * @len: size of the buffer to be allocated. - * @heap_id_mask: a bitwise maks of heap ids to allocate from - * @flags: ION_BUFFER_XXXX flags for the new buffer. - * - * The function exports a dma_buf object for the new ion buffer internally - * and returns that to the caller. So, the buffer is ready to be used by other - * drivers immediately. Returns ERR_PTR in case of failure. - */ -struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags); - -/** - * ion_free - Releases the ion buffer. - * - * @buffer: ion buffer to be released - */ -int ion_free(struct ion_buffer *buffer); - -/** - * ion_query_heaps_kernel - Returns information about available heaps to - * in-kernel clients. - * - * @hdata: pointer to array of struct ion_heap_data. - * @size: size of @hdata array. - * - * Returns the number of available heaps and populates @hdata with information - * regarding the same. When invoked with @size as 0, the function with return - * the number of available heaps without modifying @hdata. When the number of - * available heaps is higher than @size, @size is returned instead of the - * actual number of available heaps. - */ - -size_t ion_query_heaps_kernel(struct ion_heap_data *hdata, size_t size); -#else - -static inline int __ion_device_add_heap(struct ion_heap *heap, - struct module *owner) -{ - return -ENODEV; -} - -static inline int ion_heap_init_shrinker(struct ion_heap *heap) -{ - return -ENODEV; -} - -static inline int ion_heap_init_deferred_free(struct ion_heap *heap) -{ - return -ENODEV; -} - -static inline void ion_heap_freelist_add(struct ion_heap *heap, - struct ion_buffer *buffer) {} - -static inline size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) -{ - return -ENODEV; -} - -static inline size_t ion_heap_freelist_shrink(struct ion_heap *heap, - size_t size) -{ - return -ENODEV; -} - -static inline size_t ion_heap_freelist_size(struct ion_heap *heap) -{ - return -ENODEV; -} - -static inline void *ion_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -{ - return ERR_PTR(-ENODEV); -} - -static inline void ion_heap_unmap_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) {} - -static inline int ion_heap_map_user(struct ion_heap *heap, - struct ion_buffer *buffer, - struct vm_area_struct *vma) -{ - return -ENODEV; -} - -static inline int ion_buffer_zero(struct ion_buffer *buffer) -{ - return -EINVAL; -} - -static inline void ion_buffer_prep_noncached(struct ion_buffer *buffer) {} - -static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags) -{ - return ERR_PTR(-ENOMEM); -} - -static inline int ion_free(struct ion_buffer *buffer) -{ - return 0; -} - -static inline size_t ion_query_heaps_kernel(struct ion_heap_data *hdata, - size_t size) -{ - return 0; -} -#endif /* CONFIG_ION */ -#endif /* _ION_KERNEL_H */ diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h deleted file mode 100644 index 371e44662755..000000000000 --- a/include/uapi/linux/ion.h +++ /dev/null @@ -1,150 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * drivers/staging/android/uapi/ion.h - * - * Copyright (C) 2011 Google, Inc. - */ - -#ifndef _UAPI_LINUX_ION_H -#define _UAPI_LINUX_ION_H - -#include -#include - -/** - * ion_heap_types - list of all possible types of heaps that Android can use - * - * @ION_HEAP_TYPE_SYSTEM: Reserved heap id for ion heap that allocates - * memory using alloc_page(). Also, supports - * deferred free and allocation pools. -* @ION_HEAP_TYPE_DMA: Reserved heap id for ion heap that manages - * single CMA (contiguous memory allocator) - * region. Uses standard DMA APIs for - * managing memory within the CMA region. - */ -enum ion_heap_type { - ION_HEAP_TYPE_SYSTEM = 0, - ION_HEAP_TYPE_DMA = 2, - /* reserved range for future standard heap types */ - ION_HEAP_TYPE_CUSTOM = 16, - ION_HEAP_TYPE_MAX = 31, -}; - -/** - * ion_heap_id - list of standard heap ids that Android can use - * - * @ION_HEAP_SYSTEM Id for the ION_HEAP_TYPE_SYSTEM - * @ION_HEAP_DMA_START Start of reserved id range for heaps of type - * ION_HEAP_TYPE_DMA - * @ION_HEAP_DMA_END End of reserved id range for heaps of type - * ION_HEAP_TYPE_DMA - * @ION_HEAP_CUSTOM_START Start of reserved id range for heaps of custom - * type - * @ION_HEAP_CUSTOM_END End of reserved id range for heaps of custom - * type - */ -enum ion_heap_id { - ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM), - ION_HEAP_DMA_START = (ION_HEAP_SYSTEM << 1), - ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7), - ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1), - ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 22), -}; - -#define ION_NUM_MAX_HEAPS (32) - -/** - * allocation flags - the lower 16 bits are used by core ion, the upper 16 - * bits are reserved for use by the heaps themselves. - */ - -/* - * mappings of this buffer should be cached, ion will do cache maintenance - * when the buffer is mapped for dma - */ -#define ION_FLAG_CACHED 1 - -/** - * DOC: Ion Userspace API - * - * create a client by opening /dev/ion - * most operations handled via following ioctls - * - */ - -/** - * struct ion_allocation_data - metadata passed from userspace for allocations - * @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 - * - * Provided by userspace as an argument to the ioctl - */ -struct ion_allocation_data { - __u64 len; - __u32 heap_id_mask; - __u32 flags; - __u32 fd; - __u32 unused; -}; - -#define MAX_HEAP_NAME 32 - -/** - * struct ion_heap_data - data about a heap - * @name - first 32 characters of the heap name - * @type - heap type - * @heap_id - heap id for the heap - */ -struct ion_heap_data { - char name[MAX_HEAP_NAME]; - __u32 type; - __u32 heap_id; - __u32 reserved0; - __u32 reserved1; - __u32 reserved2; -}; - -/** - * struct ion_heap_query - collection of data about all heaps - * @cnt - total number of heaps to be copied - * @heaps - buffer to copy heap data - */ -struct ion_heap_query { - __u32 cnt; /* Total number of heaps to be copied */ - __u32 reserved0; /* align to 64bits */ - __u64 heaps; /* buffer to be populated */ - __u32 reserved1; - __u32 reserved2; -}; - -#define ION_IOC_MAGIC 'I' - -/** - * DOC: ION_IOC_ALLOC - allocate memory - * - * Takes an ion_allocation_data struct and returns it with the handle field - * populated with the opaque handle for the allocation. - */ -#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ - struct ion_allocation_data) - -/** - * DOC: ION_IOC_HEAP_QUERY - information about available heaps - * - * Takes an ion_heap_query structure and populates information about - * available Ion heaps. - */ -#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ - struct ion_heap_query) - -/** - * DOC: ION_IOC_HEAP_ABI_VERSION - return ABI version - * - * Returns ABI version for this driver - */ -#define ION_IOC_ABI_VERSION _IOR(ION_IOC_MAGIC, 9, \ - __u32) -#endif /* _UAPI_LINUX_ION_H */ diff --git a/kernel/configs/android-recommended.config b/kernel/configs/android-recommended.config index 81e9af7dcec2..2b13c68400bd 100644 --- a/kernel/configs/android-recommended.config +++ b/kernel/configs/android-recommended.config @@ -81,7 +81,6 @@ CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_MISC=y CONFIG_INPUT_TABLET=y CONFIG_INPUT_UINPUT=y -CONFIG_ION=y CONFIG_JOYSTICK_XPAD=y CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index e93f10386e76..c917f9f2446c 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -TARGETS = android -TARGETS += arm64 +TARGETS = arm64 TARGETS += bpf TARGETS += breakpoints TARGETS += capabilities diff --git a/tools/testing/selftests/android/Makefile b/tools/testing/selftests/android/Makefile deleted file mode 100644 index 9258306cafe9..000000000000 --- a/tools/testing/selftests/android/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -SUBDIRS := ion - -TEST_PROGS := run.sh - -.PHONY: all clean - -include ../lib.mk - -all: - @for DIR in $(SUBDIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$DIR; \ - mkdir $$BUILD_TARGET -p; \ - make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ - #SUBDIR test prog name should be in the form: SUBDIR_test.sh \ - TEST=$$DIR"_test.sh"; \ - if [ -e $$DIR/$$TEST ]; then \ - rsync -a $$DIR/$$TEST $$BUILD_TARGET/; \ - fi \ - done - -override define INSTALL_RULE - mkdir -p $(INSTALL_PATH) -install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) - - @for SUBDIR in $(SUBDIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$SUBDIR; \ - mkdir $$BUILD_TARGET -p; \ - $(MAKE) OUTPUT=$$BUILD_TARGET -C $$SUBDIR INSTALL_PATH=$(INSTALL_PATH)/$$SUBDIR install; \ - done; -endef - -override define CLEAN - @for DIR in $(SUBDIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$DIR; \ - mkdir $$BUILD_TARGET -p; \ - make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ - done -endef diff --git a/tools/testing/selftests/android/config b/tools/testing/selftests/android/config deleted file mode 100644 index b4ad748a9dd9..000000000000 --- a/tools/testing/selftests/android/config +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_ANDROID=y -CONFIG_STAGING=y -CONFIG_ION=y -CONFIG_ION_SYSTEM_HEAP=y -CONFIG_DRM_VGEM=y diff --git a/tools/testing/selftests/android/ion/.gitignore b/tools/testing/selftests/android/ion/.gitignore deleted file mode 100644 index 78eae9972bb1..000000000000 --- a/tools/testing/selftests/android/ion/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -ionapp_export -ionapp_import -ionmap_test diff --git a/tools/testing/selftests/android/ion/Makefile b/tools/testing/selftests/android/ion/Makefile deleted file mode 100644 index 42b71f005332..000000000000 --- a/tools/testing/selftests/android/ion/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/ -I../../../../../usr/include/ -CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g - -TEST_GEN_FILES := ionapp_export ionapp_import ionmap_test - -all: $(TEST_GEN_FILES) - -$(TEST_GEN_FILES): ipcsocket.c ionutils.c - -TEST_PROGS := ion_test.sh - -KSFT_KHDR_INSTALL := 1 -top_srcdir = ../../../../.. -include ../../lib.mk - -$(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c -$(OUTPUT)/ionapp_import: ionapp_import.c ipcsocket.c ionutils.c -$(OUTPUT)/ionmap_test: ionmap_test.c ionutils.c ipcsocket.c diff --git a/tools/testing/selftests/android/ion/README b/tools/testing/selftests/android/ion/README deleted file mode 100644 index 21783e9c451e..000000000000 --- a/tools/testing/selftests/android/ion/README +++ /dev/null @@ -1,101 +0,0 @@ -ION BUFFER SHARING UTILITY -========================== -File: ion_test.sh : Utility to test ION driver buffer sharing mechanism. -Author: Pintu Kumar - -Introduction: -------------- -This is a test utility to verify ION buffer sharing in user space -between 2 independent processes. -It uses unix domain socket (with SCM_RIGHTS) as IPC to transfer an FD to -another process to share the same buffer. -This utility demonstrates how ION buffer sharing can be implemented between -two user space processes, using various heap types. -The following heap types are supported by ION driver. -ION_HEAP_TYPE_SYSTEM (0) -ION_HEAP_TYPE_SYSTEM_CONTIG (1) -ION_HEAP_TYPE_CARVEOUT (2) -ION_HEAP_TYPE_CHUNK (3) -ION_HEAP_TYPE_DMA (4) - -By default only the SYSTEM and SYSTEM_CONTIG heaps are supported. -Each heap is associated with the respective heap id. -This utility is designed in the form of client/server program. -The server part (ionapp_export) is the exporter of the buffer. -It is responsible for creating an ION client, allocating the buffer based on -the heap id, writing some data to this buffer and then exporting the FD -(associated with this buffer) to another process using socket IPC. -This FD is called as buffer FD (which is different than the ION client FD). - -The client part (ionapp_import) is the importer of the buffer. -It retrives the FD from the socket data and installs into its address space. -This new FD internally points to the same kernel buffer. -So first it reads the data that is stored in this buffer and prints it. -Then it writes the different size of data (it could be different data) to the -same buffer. -Finally the buffer FD must be closed by both the exporter and importer. -Thus the same kernel buffer is shared among two user space processes using -ION driver and only one time allocation. - -Prerequisite: -------------- -This utility works only if /dev/ion interface is present. -The following configs needs to be enabled in kernel to include ion driver. -CONFIG_ANDROID=y -CONFIG_STAGING=y -CONFIG_ION=y -CONFIG_ION_SYSTEM_HEAP=y - -This utility requires to be run as root user. - - -Compile and test: ------------------ -This utility is made to be run as part of kselftest framework in kernel. -To compile and run using kselftest you can simply do the following from the -kernel top directory. -linux$ make TARGETS=android kselftest -Or you can also use: -linux$ make -C tools/testing/selftests TARGETS=android run_tests -Using the selftest it can directly execute the ion_test.sh script to test the -buffer sharing using ion system heap. -Currently the heap size is hard coded as just 10 bytes inside this script. -You need to be a root user to run under selftest. - -You can also compile and test manually using the following steps: -ion$ make -These will generate 2 executable: ionapp_export, ionapp_import -Now you can run the export and import manually by specifying the heap type -and the heap size. -You can also directly execute the shell script to run the test automatically. -Simply use the following command to run the test. -ion$ sudo ./ion_test.sh - -Test Results: -------------- -The utility is verified on Ubuntu-32 bit system with Linux Kernel 4.14. -Here is the snapshot of the test result using kselftest. - -linux# make TARGETS=android kselftest -heap_type: 0, heap_size: 10 --------------------------------------- -heap type: 0 - heap id: 1 -heap name: ion_system_heap --------------------------------------- -Fill buffer content: -0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd -Sharing fd: 6, Client fd: 5 -: buffer release successfully.... -Received buffer fd: 4 -Read buffer content: -0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0x0 0x0 0x0 0x0 0x0 0x0 -0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 -Fill buffer content: -0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd -0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd 0xfd -0xfd 0xfd -: buffer release successfully.... -ion_test.sh: heap_type: 0 - [PASS] - -ion_test.sh: done diff --git a/tools/testing/selftests/android/ion/ion.h b/tools/testing/selftests/android/ion/ion.h deleted file mode 100644 index 33db23018abf..000000000000 --- a/tools/testing/selftests/android/ion/ion.h +++ /dev/null @@ -1,134 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * ion.h - * - * Copyright (C) 2011 Google, Inc. - */ - -/* This file is copied from drivers/staging/android/uapi/ion.h - * This local copy is required for the selftest to pass, when build - * outside the kernel source tree. - * Please keep this file in sync with its original file until the - * ion driver is moved outside the staging tree. - */ - -#ifndef _UAPI_LINUX_ION_H -#define _UAPI_LINUX_ION_H - -#include -#include - -/** - * enum ion_heap_types - list of all possible types of heaps - * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc - * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc - * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved - * carveout heap, allocations are physically - * contiguous - * @ION_HEAP_TYPE_DMA: memory allocated via DMA API - * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask - * is used to identify the heaps, so only 32 - * total heap types are supported - */ -enum ion_heap_type { - ION_HEAP_TYPE_SYSTEM, - ION_HEAP_TYPE_SYSTEM_CONTIG, - ION_HEAP_TYPE_CARVEOUT, - ION_HEAP_TYPE_CHUNK, - ION_HEAP_TYPE_DMA, - ION_HEAP_TYPE_CUSTOM, /* - * must be last so device specific heaps always - * are at the end of this enum - */ -}; - -#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) - -/** - * allocation flags - the lower 16 bits are used by core ion, the upper 16 - * bits are reserved for use by the heaps themselves. - */ - -/* - * mappings of this buffer should be cached, ion will do cache maintenance - * when the buffer is mapped for dma - */ -#define ION_FLAG_CACHED 1 - -/** - * DOC: Ion Userspace API - * - * create a client by opening /dev/ion - * most operations handled via following ioctls - * - */ - -/** - * struct ion_allocation_data - metadata passed from userspace for allocations - * @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 - * - * Provided by userspace as an argument to the ioctl - */ -struct ion_allocation_data { - __u64 len; - __u32 heap_id_mask; - __u32 flags; - __u32 fd; - __u32 unused; -}; - -#define MAX_HEAP_NAME 32 - -/** - * struct ion_heap_data - data about a heap - * @name - first 32 characters of the heap name - * @type - heap type - * @heap_id - heap id for the heap - */ -struct ion_heap_data { - char name[MAX_HEAP_NAME]; - __u32 type; - __u32 heap_id; - __u32 reserved0; - __u32 reserved1; - __u32 reserved2; -}; - -/** - * struct ion_heap_query - collection of data about all heaps - * @cnt - total number of heaps to be copied - * @heaps - buffer to copy heap data - */ -struct ion_heap_query { - __u32 cnt; /* Total number of heaps to be copied */ - __u32 reserved0; /* align to 64bits */ - __u64 heaps; /* buffer to be populated */ - __u32 reserved1; - __u32 reserved2; -}; - -#define ION_IOC_MAGIC 'I' - -/** - * DOC: ION_IOC_ALLOC - allocate memory - * - * Takes an ion_allocation_data struct and returns it with the handle field - * populated with the opaque handle for the allocation. - */ -#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ - struct ion_allocation_data) - -/** - * DOC: ION_IOC_HEAP_QUERY - information about available heaps - * - * Takes an ion_heap_query structure and populates information about - * available Ion heaps. - */ -#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ - struct ion_heap_query) - -#endif /* _UAPI_LINUX_ION_H */ diff --git a/tools/testing/selftests/android/ion/ion_test.sh b/tools/testing/selftests/android/ion/ion_test.sh deleted file mode 100755 index 69e676cfc94e..000000000000 --- a/tools/testing/selftests/android/ion/ion_test.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -heapsize=4096 -TCID="ion_test.sh" -errcode=0 - -# Kselftest framework requirement - SKIP code is 4. -ksft_skip=4 - -run_test() -{ - heaptype=$1 - ./ionapp_export -i $heaptype -s $heapsize & - sleep 1 - ./ionapp_import - if [ $? -ne 0 ]; then - echo "$TCID: heap_type: $heaptype - [FAIL]" - errcode=1 - else - echo "$TCID: heap_type: $heaptype - [PASS]" - fi - sleep 1 - echo "" -} - -check_root() -{ - uid=$(id -u) - if [ $uid -ne 0 ]; then - echo $TCID: must be run as root >&2 - exit $ksft_skip - fi -} - -check_device() -{ - DEVICE=/dev/ion - if [ ! -e $DEVICE ]; then - echo $TCID: No $DEVICE device found >&2 - echo $TCID: May be CONFIG_ION is not set >&2 - exit $ksft_skip - fi -} - -main_function() -{ - check_device - check_root - - # ION_SYSTEM_HEAP TEST - run_test 0 - # ION_SYSTEM_CONTIG_HEAP TEST - run_test 1 -} - -main_function -echo "$TCID: done" -exit $errcode diff --git a/tools/testing/selftests/android/ion/ionapp_export.c b/tools/testing/selftests/android/ion/ionapp_export.c deleted file mode 100644 index 063b7830d1bd..000000000000 --- a/tools/testing/selftests/android/ion/ionapp_export.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ionapp_export.c - * - * It is a user space utility to create and export android - * ion memory buffer fd to another process using unix domain socket as IPC. - * This acts like a server for ionapp_import(client). - * So, this server has to be started first before the client. - * - * Copyright (C) 2017 Pintu Kumar - */ - -#include -#include -#include -#include -#include -#include -#include "ionutils.h" -#include "ipcsocket.h" - - -void print_usage(int argc, char *argv[]) -{ - printf("Usage: %s [-h ] [-i ] [-s ]\n", - argv[0]); -} - -int main(int argc, char *argv[]) -{ - int opt, ret, status, heapid; - int sockfd, client_fd, shared_fd; - unsigned char *map_buf; - unsigned long map_len, heap_type, heap_size, flags; - struct ion_buffer_info info; - struct socket_info skinfo; - - if (argc < 2) { - print_usage(argc, argv); - return -1; - } - - heap_size = 0; - flags = 0; - heap_type = ION_HEAP_TYPE_SYSTEM; - - while ((opt = getopt(argc, argv, "hi:s:")) != -1) { - switch (opt) { - case 'h': - print_usage(argc, argv); - exit(0); - break; - case 'i': - heapid = atoi(optarg); - switch (heapid) { - case 0: - heap_type = ION_HEAP_TYPE_SYSTEM; - break; - case 1: - heap_type = ION_HEAP_TYPE_SYSTEM_CONTIG; - break; - default: - printf("ERROR: heap type not supported\n"); - exit(1); - } - break; - case 's': - heap_size = atoi(optarg); - break; - default: - print_usage(argc, argv); - exit(1); - break; - } - } - - if (heap_size <= 0) { - printf("heap_size cannot be 0\n"); - print_usage(argc, argv); - exit(1); - } - - printf("heap_type: %ld, heap_size: %ld\n", heap_type, heap_size); - info.heap_type = heap_type; - info.heap_size = heap_size; - info.flag_type = flags; - - /* This is server: open the socket connection first */ - /* Here; 1 indicates server or exporter */ - status = opensocket(&sockfd, SOCKET_NAME, 1); - if (status < 0) { - fprintf(stderr, "<%s>: Failed opensocket.\n", __func__); - goto err_socket; - } - skinfo.sockfd = sockfd; - - ret = ion_export_buffer_fd(&info); - if (ret < 0) { - fprintf(stderr, "FAILED: ion_get_buffer_fd\n"); - goto err_export; - } - client_fd = info.ionfd; - shared_fd = info.buffd; - map_buf = info.buffer; - map_len = info.buflen; - write_buffer(map_buf, map_len); - - /* share ion buf fd with other user process */ - printf("Sharing fd: %d, Client fd: %d\n", shared_fd, client_fd); - skinfo.datafd = shared_fd; - skinfo.buflen = map_len; - - ret = socket_send_fd(&skinfo); - if (ret < 0) { - fprintf(stderr, "FAILED: socket_send_fd\n"); - goto err_send; - } - -err_send: -err_export: - ion_close_buffer_fd(&info); - -err_socket: - closesocket(sockfd, SOCKET_NAME); - - return 0; -} diff --git a/tools/testing/selftests/android/ion/ionapp_import.c b/tools/testing/selftests/android/ion/ionapp_import.c deleted file mode 100644 index 54b580cb04f6..000000000000 --- a/tools/testing/selftests/android/ion/ionapp_import.c +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ionapp_import.c - * - * It is a user space utility to receive android ion memory buffer fd - * over unix domain socket IPC that can be exported by ionapp_export. - * This acts like a client for ionapp_export. - * - * Copyright (C) 2017 Pintu Kumar - */ - -#include -#include -#include -#include -#include "ionutils.h" -#include "ipcsocket.h" - - -int main(void) -{ - int ret, status; - int sockfd, shared_fd; - unsigned char *map_buf; - unsigned long map_len; - struct ion_buffer_info info; - struct socket_info skinfo; - - /* This is the client part. Here 0 means client or importer */ - status = opensocket(&sockfd, SOCKET_NAME, 0); - if (status < 0) { - fprintf(stderr, "No exporter exists...\n"); - ret = status; - goto err_socket; - } - - skinfo.sockfd = sockfd; - - ret = socket_receive_fd(&skinfo); - if (ret < 0) { - fprintf(stderr, "Failed: socket_receive_fd\n"); - goto err_recv; - } - - shared_fd = skinfo.datafd; - printf("Received buffer fd: %d\n", shared_fd); - if (shared_fd <= 0) { - fprintf(stderr, "ERROR: improper buf fd\n"); - ret = -1; - goto err_fd; - } - - memset(&info, 0, sizeof(info)); - info.buffd = shared_fd; - info.buflen = ION_BUFFER_LEN; - - ret = ion_import_buffer_fd(&info); - if (ret < 0) { - fprintf(stderr, "Failed: ion_use_buffer_fd\n"); - goto err_import; - } - - map_buf = info.buffer; - map_len = info.buflen; - read_buffer(map_buf, map_len); - - /* Write probably new data to the same buffer again */ - map_len = ION_BUFFER_LEN; - write_buffer(map_buf, map_len); - -err_import: - ion_close_buffer_fd(&info); -err_fd: -err_recv: -err_socket: - closesocket(sockfd, SOCKET_NAME); - - return ret; -} diff --git a/tools/testing/selftests/android/ion/ionmap_test.c b/tools/testing/selftests/android/ion/ionmap_test.c deleted file mode 100644 index dab36b06b37d..000000000000 --- a/tools/testing/selftests/android/ion/ionmap_test.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include "ion.h" -#include "ionutils.h" - -int check_vgem(int fd) -{ - drm_version_t version = { 0 }; - char name[5]; - int ret; - - version.name_len = 4; - version.name = name; - - ret = ioctl(fd, DRM_IOCTL_VERSION, &version); - if (ret) - return 1; - - return strcmp(name, "vgem"); -} - -int open_vgem(void) -{ - int i, fd; - const char *drmstr = "/dev/dri/card"; - - fd = -1; - for (i = 0; i < 16; i++) { - char name[80]; - - sprintf(name, "%s%u", drmstr, i); - - fd = open(name, O_RDWR); - if (fd < 0) - continue; - - if (check_vgem(fd)) { - close(fd); - continue; - } else { - break; - } - - } - return fd; -} - -int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle) -{ - struct drm_prime_handle import_handle = { 0 }; - int ret; - - import_handle.fd = dma_buf_fd; - import_handle.flags = 0; - import_handle.handle = 0; - - ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle); - if (ret == 0) - *handle = import_handle.handle; - return ret; -} - -void close_handle(int vgem_fd, uint32_t handle) -{ - struct drm_gem_close close = { 0 }; - - close.handle = handle; - ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close); -} - -int main() -{ - int ret, vgem_fd; - struct ion_buffer_info info; - uint32_t handle = 0; - struct dma_buf_sync sync = { 0 }; - - info.heap_type = ION_HEAP_TYPE_SYSTEM; - info.heap_size = 4096; - info.flag_type = ION_FLAG_CACHED; - - ret = ion_export_buffer_fd(&info); - if (ret < 0) { - printf("ion buffer alloc failed\n"); - return -1; - } - - vgem_fd = open_vgem(); - if (vgem_fd < 0) { - ret = vgem_fd; - printf("Failed to open vgem\n"); - goto out_ion; - } - - ret = import_vgem_fd(vgem_fd, info.buffd, &handle); - - if (ret < 0) { - printf("Failed to import buffer\n"); - goto out_vgem; - } - - sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW; - ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); - if (ret) - printf("sync start failed %d\n", errno); - - memset(info.buffer, 0xff, 4096); - - sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; - ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); - if (ret) - printf("sync end failed %d\n", errno); - - close_handle(vgem_fd, handle); - ret = 0; - -out_vgem: - close(vgem_fd); -out_ion: - ion_close_buffer_fd(&info); - printf("done.\n"); - return ret; -} diff --git a/tools/testing/selftests/android/ion/ionutils.c b/tools/testing/selftests/android/ion/ionutils.c deleted file mode 100644 index 7d1d37c4ef6a..000000000000 --- a/tools/testing/selftests/android/ion/ionutils.c +++ /dev/null @@ -1,253 +0,0 @@ -#include -#include -#include -#include -#include -//#include -#include -#include -#include "ionutils.h" -#include "ipcsocket.h" - - -void write_buffer(void *buffer, unsigned long len) -{ - int i; - unsigned char *ptr = (unsigned char *)buffer; - - if (!ptr) { - fprintf(stderr, "<%s>: Invalid buffer...\n", __func__); - return; - } - - printf("Fill buffer content:\n"); - memset(ptr, 0xfd, len); - for (i = 0; i < len; i++) - printf("0x%x ", ptr[i]); - printf("\n"); -} - -void read_buffer(void *buffer, unsigned long len) -{ - int i; - unsigned char *ptr = (unsigned char *)buffer; - - if (!ptr) { - fprintf(stderr, "<%s>: Invalid buffer...\n", __func__); - return; - } - - printf("Read buffer content:\n"); - for (i = 0; i < len; i++) - printf("0x%x ", ptr[i]); - printf("\n"); -} - -int ion_export_buffer_fd(struct ion_buffer_info *ion_info) -{ - int i, ret, ionfd, buffer_fd; - unsigned int heap_id; - unsigned long maplen; - unsigned char *map_buffer; - struct ion_allocation_data alloc_data; - struct ion_heap_query query; - struct ion_heap_data heap_data[MAX_HEAP_COUNT]; - - if (!ion_info) { - fprintf(stderr, "<%s>: Invalid ion info\n", __func__); - return -1; - } - - /* Create an ION client */ - ionfd = open(ION_DEVICE, O_RDWR); - if (ionfd < 0) { - fprintf(stderr, "<%s>: Failed to open ion client: %s\n", - __func__, strerror(errno)); - return -1; - } - - memset(&query, 0, sizeof(query)); - query.cnt = MAX_HEAP_COUNT; - query.heaps = (unsigned long int)&heap_data[0]; - /* Query ION heap_id_mask from ION heap */ - ret = ioctl(ionfd, ION_IOC_HEAP_QUERY, &query); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed: ION_IOC_HEAP_QUERY: %s\n", - __func__, strerror(errno)); - goto err_query; - } - - heap_id = MAX_HEAP_COUNT + 1; - for (i = 0; i < query.cnt; i++) { - if (heap_data[i].type == ion_info->heap_type) { - heap_id = heap_data[i].heap_id; - break; - } - } - - if (heap_id > MAX_HEAP_COUNT) { - fprintf(stderr, "<%s>: ERROR: heap type does not exists\n", - __func__); - goto err_heap; - } - - alloc_data.len = ion_info->heap_size; - alloc_data.heap_id_mask = 1 << heap_id; - alloc_data.flags = ion_info->flag_type; - - /* Allocate memory for this ION client as per heap_type */ - ret = ioctl(ionfd, ION_IOC_ALLOC, &alloc_data); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed: ION_IOC_ALLOC: %s\n", - __func__, strerror(errno)); - goto err_alloc; - } - - /* This will return a valid buffer fd */ - buffer_fd = alloc_data.fd; - maplen = alloc_data.len; - - if (buffer_fd < 0 || maplen <= 0) { - fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n", - __func__, buffer_fd, maplen); - goto err_fd_data; - } - - /* Create memory mapped buffer for the buffer fd */ - map_buffer = (unsigned char *)mmap(NULL, maplen, PROT_READ|PROT_WRITE, - MAP_SHARED, buffer_fd, 0); - if (map_buffer == MAP_FAILED) { - fprintf(stderr, "<%s>: Failed: mmap: %s\n", - __func__, strerror(errno)); - goto err_mmap; - } - - ion_info->ionfd = ionfd; - ion_info->buffd = buffer_fd; - ion_info->buffer = map_buffer; - ion_info->buflen = maplen; - - return 0; - - munmap(map_buffer, maplen); - -err_fd_data: -err_mmap: - /* in case of error: close the buffer fd */ - if (buffer_fd) - close(buffer_fd); - -err_query: -err_heap: -err_alloc: - /* In case of error: close the ion client fd */ - if (ionfd) - close(ionfd); - - return -1; -} - -int ion_import_buffer_fd(struct ion_buffer_info *ion_info) -{ - int buffd; - unsigned char *map_buf; - unsigned long map_len; - - if (!ion_info) { - fprintf(stderr, "<%s>: Invalid ion info\n", __func__); - return -1; - } - - map_len = ion_info->buflen; - buffd = ion_info->buffd; - - if (buffd < 0 || map_len <= 0) { - fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n", - __func__, buffd, map_len); - goto err_buffd; - } - - map_buf = (unsigned char *)mmap(NULL, map_len, PROT_READ|PROT_WRITE, - MAP_SHARED, buffd, 0); - if (map_buf == MAP_FAILED) { - printf("<%s>: Failed - mmap: %s\n", - __func__, strerror(errno)); - goto err_mmap; - } - - ion_info->buffer = map_buf; - ion_info->buflen = map_len; - - return 0; - -err_mmap: - if (buffd) - close(buffd); - -err_buffd: - return -1; -} - -void ion_close_buffer_fd(struct ion_buffer_info *ion_info) -{ - if (ion_info) { - /* unmap the buffer properly in the end */ - munmap(ion_info->buffer, ion_info->buflen); - /* close the buffer fd */ - if (ion_info->buffd > 0) - close(ion_info->buffd); - /* Finally, close the client fd */ - if (ion_info->ionfd > 0) - close(ion_info->ionfd); - } -} - -int socket_send_fd(struct socket_info *info) -{ - int status; - int fd, sockfd; - struct socketdata skdata; - - if (!info) { - fprintf(stderr, "<%s>: Invalid socket info\n", __func__); - return -1; - } - - sockfd = info->sockfd; - fd = info->datafd; - memset(&skdata, 0, sizeof(skdata)); - skdata.data = fd; - skdata.len = sizeof(skdata.data); - status = sendtosocket(sockfd, &skdata); - if (status < 0) { - fprintf(stderr, "<%s>: Failed: sendtosocket\n", __func__); - return -1; - } - - return 0; -} - -int socket_receive_fd(struct socket_info *info) -{ - int status; - int fd, sockfd; - struct socketdata skdata; - - if (!info) { - fprintf(stderr, "<%s>: Invalid socket info\n", __func__); - return -1; - } - - sockfd = info->sockfd; - memset(&skdata, 0, sizeof(skdata)); - status = receivefromsocket(sockfd, &skdata); - if (status < 0) { - fprintf(stderr, "<%s>: Failed: receivefromsocket\n", __func__); - return -1; - } - - fd = (int)skdata.data; - info->datafd = fd; - - return status; -} diff --git a/tools/testing/selftests/android/ion/ionutils.h b/tools/testing/selftests/android/ion/ionutils.h deleted file mode 100644 index 9941eb858576..000000000000 --- a/tools/testing/selftests/android/ion/ionutils.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __ION_UTILS_H -#define __ION_UTILS_H - -#include "ion.h" - -#define SOCKET_NAME "ion_socket" -#define ION_DEVICE "/dev/ion" - -#define ION_BUFFER_LEN 4096 -#define MAX_HEAP_COUNT ION_HEAP_TYPE_CUSTOM - -struct socket_info { - int sockfd; - int datafd; - unsigned long buflen; -}; - -struct ion_buffer_info { - int ionfd; - int buffd; - unsigned int heap_type; - unsigned int flag_type; - unsigned long heap_size; - unsigned long buflen; - unsigned char *buffer; -}; - - -/* This is used to fill the data into the mapped buffer */ -void write_buffer(void *buffer, unsigned long len); - -/* This is used to read the data from the exported buffer */ -void read_buffer(void *buffer, unsigned long len); - -/* This is used to create an ION buffer FD for the kernel buffer - * So you can export this same buffer to others in the form of FD - */ -int ion_export_buffer_fd(struct ion_buffer_info *ion_info); - -/* This is used to import or map an exported FD. - * So we point to same buffer without making a copy. Hence zero-copy. - */ -int ion_import_buffer_fd(struct ion_buffer_info *ion_info); - -/* This is used to close all references for the ION client */ -void ion_close_buffer_fd(struct ion_buffer_info *ion_info); - -/* This is used to send FD to another process using socket IPC */ -int socket_send_fd(struct socket_info *skinfo); - -/* This is used to receive FD from another process using socket IPC */ -int socket_receive_fd(struct socket_info *skinfo); - - -#endif diff --git a/tools/testing/selftests/android/ion/ipcsocket.c b/tools/testing/selftests/android/ion/ipcsocket.c deleted file mode 100644 index 7dc521002095..000000000000 --- a/tools/testing/selftests/android/ion/ipcsocket.c +++ /dev/null @@ -1,227 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ipcsocket.h" - - -int opensocket(int *sockfd, const char *name, int connecttype) -{ - int ret, temp = 1; - - if (!name || strlen(name) > MAX_SOCK_NAME_LEN) { - fprintf(stderr, "<%s>: Invalid socket name.\n", __func__); - return -1; - } - - ret = socket(PF_LOCAL, SOCK_STREAM, 0); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed socket: <%s>\n", - __func__, strerror(errno)); - return ret; - } - - *sockfd = ret; - if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, - (char *)&temp, sizeof(int)) < 0) { - fprintf(stderr, "<%s>: Failed setsockopt: <%s>\n", - __func__, strerror(errno)); - goto err; - } - - sprintf(sock_name, "/tmp/%s", name); - - if (connecttype == 1) { - /* This is for Server connection */ - struct sockaddr_un skaddr; - int clientfd; - socklen_t sklen; - - unlink(sock_name); - memset(&skaddr, 0, sizeof(skaddr)); - skaddr.sun_family = AF_LOCAL; - strcpy(skaddr.sun_path, sock_name); - - ret = bind(*sockfd, (struct sockaddr *)&skaddr, - SUN_LEN(&skaddr)); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed bind: <%s>\n", - __func__, strerror(errno)); - goto err; - } - - ret = listen(*sockfd, 5); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed listen: <%s>\n", - __func__, strerror(errno)); - goto err; - } - - memset(&skaddr, 0, sizeof(skaddr)); - sklen = sizeof(skaddr); - - ret = accept(*sockfd, (struct sockaddr *)&skaddr, - (socklen_t *)&sklen); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed accept: <%s>\n", - __func__, strerror(errno)); - goto err; - } - - clientfd = ret; - *sockfd = clientfd; - } else { - /* This is for client connection */ - struct sockaddr_un skaddr; - - memset(&skaddr, 0, sizeof(skaddr)); - skaddr.sun_family = AF_LOCAL; - strcpy(skaddr.sun_path, sock_name); - - ret = connect(*sockfd, (struct sockaddr *)&skaddr, - SUN_LEN(&skaddr)); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed connect: <%s>\n", - __func__, strerror(errno)); - goto err; - } - } - - return 0; - -err: - if (*sockfd) - close(*sockfd); - - return ret; -} - -int sendtosocket(int sockfd, struct socketdata *skdata) -{ - int ret, buffd; - unsigned int len; - char cmsg_b[CMSG_SPACE(sizeof(int))]; - struct cmsghdr *cmsg; - struct msghdr msgh; - struct iovec iov; - struct timeval timeout; - fd_set selFDs; - - if (!skdata) { - fprintf(stderr, "<%s>: socketdata is NULL\n", __func__); - return -1; - } - - FD_ZERO(&selFDs); - FD_SET(0, &selFDs); - FD_SET(sockfd, &selFDs); - timeout.tv_sec = 20; - timeout.tv_usec = 0; - - ret = select(sockfd+1, NULL, &selFDs, NULL, &timeout); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed select: <%s>\n", - __func__, strerror(errno)); - return -1; - } - - if (FD_ISSET(sockfd, &selFDs)) { - buffd = skdata->data; - len = skdata->len; - memset(&msgh, 0, sizeof(msgh)); - msgh.msg_control = &cmsg_b; - msgh.msg_controllen = CMSG_LEN(len); - iov.iov_base = "OK"; - iov.iov_len = 2; - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(len); - memcpy(CMSG_DATA(cmsg), &buffd, len); - - ret = sendmsg(sockfd, &msgh, MSG_DONTWAIT); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed sendmsg: <%s>\n", - __func__, strerror(errno)); - return -1; - } - } - - return 0; -} - -int receivefromsocket(int sockfd, struct socketdata *skdata) -{ - int ret, buffd; - unsigned int len = 0; - char cmsg_b[CMSG_SPACE(sizeof(int))]; - struct cmsghdr *cmsg; - struct msghdr msgh; - struct iovec iov; - fd_set recvFDs; - char data[32]; - - if (!skdata) { - fprintf(stderr, "<%s>: socketdata is NULL\n", __func__); - return -1; - } - - FD_ZERO(&recvFDs); - FD_SET(0, &recvFDs); - FD_SET(sockfd, &recvFDs); - - ret = select(sockfd+1, &recvFDs, NULL, NULL, NULL); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed select: <%s>\n", - __func__, strerror(errno)); - return -1; - } - - if (FD_ISSET(sockfd, &recvFDs)) { - len = sizeof(buffd); - memset(&msgh, 0, sizeof(msgh)); - msgh.msg_control = &cmsg_b; - msgh.msg_controllen = CMSG_LEN(len); - iov.iov_base = data; - iov.iov_len = sizeof(data)-1; - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - cmsg = CMSG_FIRSTHDR(&msgh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(len); - - ret = recvmsg(sockfd, &msgh, MSG_DONTWAIT); - if (ret < 0) { - fprintf(stderr, "<%s>: Failed recvmsg: <%s>\n", - __func__, strerror(errno)); - return -1; - } - - memcpy(&buffd, CMSG_DATA(cmsg), len); - skdata->data = buffd; - skdata->len = len; - } - return 0; -} - -int closesocket(int sockfd, char *name) -{ - char sockname[MAX_SOCK_NAME_LEN]; - - if (sockfd) - close(sockfd); - sprintf(sockname, "/tmp/%s", name); - unlink(sockname); - shutdown(sockfd, 2); - - return 0; -} diff --git a/tools/testing/selftests/android/ion/ipcsocket.h b/tools/testing/selftests/android/ion/ipcsocket.h deleted file mode 100644 index b3e84498a8a1..000000000000 --- a/tools/testing/selftests/android/ion/ipcsocket.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef _IPCSOCKET_H -#define _IPCSOCKET_H - - -#define MAX_SOCK_NAME_LEN 64 - -char sock_name[MAX_SOCK_NAME_LEN]; - -/* This structure is responsible for holding the IPC data - * data: hold the buffer fd - * len: just the length of 32-bit integer fd - */ -struct socketdata { - int data; - unsigned int len; -}; - -/* This API is used to open the IPC socket connection - * name: implies a unique socket name in the system - * connecttype: implies server(0) or client(1) - */ -int opensocket(int *sockfd, const char *name, int connecttype); - -/* This is the API to send socket data over IPC socket */ -int sendtosocket(int sockfd, struct socketdata *data); - -/* This is the API to receive socket data over IPC socket */ -int receivefromsocket(int sockfd, struct socketdata *data); - -/* This is the API to close the socket connection */ -int closesocket(int sockfd, char *name); - - -#endif diff --git a/tools/testing/selftests/android/run.sh b/tools/testing/selftests/android/run.sh deleted file mode 100755 index dd8edf291454..000000000000 --- a/tools/testing/selftests/android/run.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -(cd ion; ./ion_test.sh)