Skip to content

Commit

Permalink
ANDROID: staging: android: ion: Expose total heap and pool sizes via …
Browse files Browse the repository at this point in the history
…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: Suren Baghdasaryan <[email protected]>
  • Loading branch information
surenbaghdasaryan authored and TE-N-JiLuo committed Oct 30, 2020
1 parent 42099e0 commit 7d54911
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 2 deletions.
27 changes: 27 additions & 0 deletions Documentation/ABI/testing/sysfs-kernel-ion
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
What: /sys/kernel/ion
Date: Dec 2019
KernelVersion: 4.14.158
Contact: Suren Baghdasaryan <[email protected]>,
Sandeep Patil <[email protected]>
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 <[email protected]>,
Sandeep Patil <[email protected]>
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 <[email protected]>,
Sandeep Patil <[email protected]>
Description:
The total_pools_kb file is read-only and specifies how much
memory in Kb is allocated to ION pools.
11 changes: 11 additions & 0 deletions drivers/staging/android/ion/heaps/ion_page_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/staging/android/ion/heaps/ion_page_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions drivers/staging/android/ion/heaps/ion_system_heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 = {
Expand Down
72 changes: 70 additions & 2 deletions drivers/staging/android/ion/ion.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,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;
Expand All @@ -450,14 +507,25 @@ 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);
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);
9 changes: 9 additions & 0 deletions drivers/staging/android/ion/ion_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include "ion_private.h"

static atomic_long_t total_heap_bytes;

/* 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,
Expand Down Expand Up @@ -65,6 +67,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,

INIT_LIST_HEAD(&buffer->attachments);
mutex_init(&buffer->lock);
atomic_long_add(len, &total_heap_bytes);
return buffer;

err1:
Expand Down Expand Up @@ -215,6 +218,7 @@ int ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer)
}

heap = buffer->heap;
atomic_long_sub(buffer->size, &total_heap_bytes);

if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
ion_heap_freelist_add(heap, buffer);
Expand Down Expand Up @@ -251,3 +255,8 @@ void ion_buffer_kmap_put(struct ion_buffer *buffer)
buffer->vaddr = NULL;
}
}

u64 ion_get_total_heap_bytes(void)
{
return atomic_long_read(&total_heap_bytes);
}
2 changes: 2 additions & 0 deletions drivers/staging/android/ion/ion_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ 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 */
2 changes: 2 additions & 0 deletions include/linux/ion.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct ion_buffer {
* 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
Expand All @@ -67,6 +68,7 @@ struct ion_heap_ops {
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);
};

/**
Expand Down

0 comments on commit 7d54911

Please sign in to comment.