Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d872160f authored by Sandeep Patil's avatar Sandeep Patil Committed by Alistair Delva
Browse files

staging: ion: make system and contig heaps modular



Add symmetric heap add/remove APIs and export symbols from
ion core that are needed to make both heaps modular.

Bug: 133508579
Test: ion-unit-test, rmmod, modprobe

Change-Id: Ic5f40936531936c9bfab48ea147108c019d28e2c
Signed-off-by: default avatarSandeep Patil <sspatil@google.com>
parent ef878199
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
config ION_SYSTEM_HEAP
	bool "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_SYSTEM_CONTIG_HEAP
	bool "Ion system contig heap"
	tristate "Ion system contig heap"
	depends on ION
	help
	  Choose this option to enable Ion system contig heap. The system contig heap
+3 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o
obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_sys_heap.o
ion_sys_heap-y := ion_system_heap.o ion_page_pool.o

obj-$(CONFIG_ION_SYSTEM_CONTIG_HEAP) += ion_system_contig_heap.o
obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o
+14 −22
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/highmem.h>
#include <linux/ion.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>

@@ -81,31 +82,22 @@ static struct ion_heap_ops kmalloc_ops = {
	.map_user = ion_heap_map_user,
};

static struct ion_heap *__ion_system_contig_heap_create(void)
{
	struct ion_heap *heap;

	heap = kzalloc(sizeof(*heap), GFP_KERNEL);
	if (!heap)
		return ERR_PTR(-ENOMEM);
	heap->ops = &kmalloc_ops;
	heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG;
	heap->name = "ion_system_contig_heap";
static struct ion_heap contig_heap = {
	.ops = &kmalloc_ops,
	.type = ION_HEAP_TYPE_SYSTEM_CONTIG,
	.name = "ion_system_contig_heap",
};

	return heap;
static int __init ion_system_contig_heap_init(void)
{
	return ion_device_add_heap(&contig_heap);
}

static int ion_system_contig_heap_create(void)
static void __exit ion_system_contig_heap_exit(void)
{
	struct ion_heap *heap;

	heap = __ion_system_contig_heap_create();
	if (IS_ERR(heap))
		return PTR_ERR(heap);

	ion_device_add_heap(heap);

	return 0;
	ion_device_remove_heap(&contig_heap);
}
device_initcall(ion_system_contig_heap_create);

module_init(ion_system_contig_heap_init);
module_exit(ion_system_contig_heap_exit);
MODULE_LICENSE("GPL v2");
+30 −37
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/highmem.h>
#include <linux/ion.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -204,15 +205,6 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
	return nr_total;
}

static struct ion_heap_ops system_heap_ops = {
	.allocate = ion_system_heap_allocate,
	.free = ion_system_heap_free,
	.map_kernel = ion_heap_map_kernel,
	.unmap_kernel = ion_heap_unmap_kernel,
	.map_user = ion_heap_map_user,
	.shrink = ion_system_heap_shrink,
};

static void ion_system_heap_destroy_pools(struct ion_page_pool **pools)
{
	int i;
@@ -246,38 +238,39 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools)
	return -ENOMEM;
}

static struct ion_heap *__ion_system_heap_create(void)
{
	struct ion_system_heap *heap;

	heap = kzalloc(sizeof(*heap), GFP_KERNEL);
	if (!heap)
		return ERR_PTR(-ENOMEM);
	heap->heap.ops = &system_heap_ops;
	heap->heap.type = ION_HEAP_TYPE_SYSTEM;
	heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;

	if (ion_system_heap_create_pools(heap->pools))
		goto free_heap;

	return &heap->heap;
static struct ion_heap_ops system_heap_ops = {
	.allocate = ion_system_heap_allocate,
	.free = ion_system_heap_free,
	.map_kernel = ion_heap_map_kernel,
	.unmap_kernel = ion_heap_unmap_kernel,
	.map_user = ion_heap_map_user,
	.shrink = ion_system_heap_shrink,
};

free_heap:
	kfree(heap);
	return ERR_PTR(-ENOMEM);
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 ion_system_heap_create(void)
static int __init ion_system_heap_init(void)
{
	struct ion_heap *heap;

	heap = __ion_system_heap_create();
	if (IS_ERR(heap))
		return PTR_ERR(heap);
	heap->name = "ion_system_heap";
	int ret = ion_system_heap_create_pools(system_heap.pools);
	if (ret)
		return ret;

	ion_device_add_heap(heap);
	return ion_device_add_heap(&system_heap.heap);
}

	return 0;
static void __exit ion_system_heap_exit(void)
{
	ion_device_remove_heap(&system_heap.heap);
	ion_system_heap_destroy_pools(system_heap.pools);
}
device_initcall(ion_system_heap_create);

module_init(ion_system_heap_init);
module_exit(ion_system_heap_exit);
MODULE_LICENSE("GPL v2");
+46 −8
Original line number Diff line number Diff line
@@ -222,28 +222,36 @@ static int debug_shrink_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
			debug_shrink_set, "%llu\n");

void ion_device_add_heap(struct ion_heap *heap)
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->ops->allocate || !heap->ops->free)
		pr_err("%s: can not add heap with invalid ops struct.\n",
		       __func__);
	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)
		ion_heap_init_deferred_free(heap);
	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)
		if (ret) {
			pr_err("%s: Failed to register shrinker\n", __func__);
			goto out_heap_cleanup;
		}
	}

	heap->num_of_buffers = 0;
@@ -273,6 +281,7 @@ void ion_device_add_heap(struct ion_heap *heap)
				    &debug_shrink_fops);
	}

	heap->debugfs_dir = heap_root;
	down_write(&dev->lock);
	heap->id = heap_id++;
	/*
@@ -284,8 +293,37 @@ void ion_device_add_heap(struct ion_heap *heap)

	dev->heap_cnt++;
	up_write(&dev->lock);

	return 0;

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);
	up_write(&dev->lock);
}
EXPORT_SYMBOL(ion_device_add_heap);
EXPORT_SYMBOL(ion_device_remove_heap);

static int ion_device_create(void)
{
Loading