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

Commit 2ec79b55 authored by Suren Baghdasaryan's avatar Suren Baghdasaryan Committed by Matthias Maennich
Browse files

ANDROID: staging: android: ion: Expose total heap and pool sizes via sysfs



Add sysfs attributes to track ion total heap and pool memory allocations.
The following sysfs attributes are added:

/sys/kernel/ion/total_heaps_kb
/sys/kernel/ion/total_pools_kb

Bug: 138148041
Bug: 154238995
Test: adb shell cat /sys/kernel/ion/*
Change-Id: If92770dc3389af865c619525f04d3ba0e013b244
Signed-off-by: default avatarSuren Baghdasaryan <surenb@google.com>
parent 1d77161f
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
What:		/sys/kernel/ion
Date:		Dec 2019
KernelVersion:	4.14.158
Contact:	Suren Baghdasaryan <surenb@google.com>,
		Sandeep Patil <sspatil@google.com>
Description:
		The /sys/kernel/ion directory contains a snapshot of the
		internal state of ION memory heaps and pools.
Users:		kernel memory tuning tools

What:		/sys/kernel/ion/total_heaps_kb
Date:		Dec 2019
KernelVersion:	4.14.158
Contact:	Suren Baghdasaryan <surenb@google.com>,
		Sandeep Patil <sspatil@google.com>
Description:
		The total_heaps_kb file is read-only and specifies how much
		memory in Kb is allocated to ION heaps.

What:		/sys/kernel/ion/total_pools_kb
Date:		Dec 2019
KernelVersion:	4.14.158
Contact:	Suren Baghdasaryan <surenb@google.com>,
		Sandeep Patil <sspatil@google.com>
Description:
		The total_pools_kb file is read-only and specifies how much
		memory in Kb is allocated to ION pools.
+11 −0
Original line number Diff line number Diff line
@@ -97,6 +97,17 @@ static int ion_page_pool_total(struct ion_page_pool *pool, bool high)
	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;
}

int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
			 int nr_to_scan)
{
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ 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
+14 −0
Original line number Diff line number Diff line
@@ -208,6 +208,19 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
	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;
@@ -245,6 +258,7 @@ 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 = {
+70 −2
Original line number Diff line number Diff line
@@ -424,6 +424,63 @@ void ion_device_remove_heap(struct ion_heap *heap)
}
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;
@@ -440,8 +497,13 @@ static int ion_device_create(void)
	ret = misc_register(&idev->dev);
	if (ret) {
		pr_err("ion: failed to register misc device.\n");
		kfree(idev);
		return ret;
		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);
@@ -449,5 +511,11 @@ static int ion_device_create(void)
	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);
Loading