ANDROID: dma-buf: heaps: Add a sysfs file to report total pool size.
In order to help with memory accounting, expose the total pool size of all DMA-BUF heaps at /sys/kernel/dma_heap/total_pools_kb. This information will be exposed as part of Android Bugreport[1]. [1]: https://android-review.googlesource.com/q/topic:%22b%252F167709539%22+(status:open%20OR%20status:merged) Bug: 167709539 Change-Id: I6a1b52517e73103122690f6567f4f295db9ca1ad Signed-off-by: Hridya Valsaraju <hridya@google.com>
This commit is contained in:
7
Documentation/ABI/testing/sysfs-kernel-dmaheap
Normal file
7
Documentation/ABI/testing/sysfs-kernel-dmaheap
Normal file
@@ -0,0 +1,7 @@
|
||||
What: /sys/kernel/dma_heap/total_pools_kb
|
||||
Date: Feb 2021
|
||||
KernelVersion: 5.10
|
||||
Contact: Hridya Valsaraju <hridya@google.com>,
|
||||
Description:
|
||||
The total_pools_kb file is read-only and specifies how much
|
||||
memory in Kb is allocated to DMA-BUF heap pools.
|
||||
@@ -383,21 +383,81 @@ static char *dma_heap_devnode(struct device *dev, umode_t *mode)
|
||||
return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
static ssize_t total_pools_kb_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct dma_heap *heap;
|
||||
u64 total_pool_size = 0;
|
||||
|
||||
mutex_lock(&heap_list_lock);
|
||||
list_for_each_entry(heap, &heap_list, list) {
|
||||
if (heap->ops->get_pool_size)
|
||||
total_pool_size += heap->ops->get_pool_size(heap);
|
||||
}
|
||||
mutex_unlock(&heap_list_lock);
|
||||
|
||||
return sysfs_emit(buf, "%llu\n", total_pool_size / 1024);
|
||||
}
|
||||
|
||||
static struct kobj_attribute total_pools_kb_attr =
|
||||
__ATTR_RO(total_pools_kb);
|
||||
|
||||
static struct attribute *dma_heap_sysfs_attrs[] = {
|
||||
&total_pools_kb_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
ATTRIBUTE_GROUPS(dma_heap_sysfs);
|
||||
|
||||
static struct kobject *dma_heap_kobject;
|
||||
|
||||
static int dma_heap_sysfs_setup(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dma_heap_kobject = kobject_create_and_add("dma_heap", kernel_kobj);
|
||||
if (!dma_heap_kobject)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = sysfs_create_groups(dma_heap_kobject, dma_heap_sysfs_groups);
|
||||
if (ret) {
|
||||
kobject_put(dma_heap_kobject);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dma_heap_sysfs_teardown(void)
|
||||
{
|
||||
kobject_put(dma_heap_kobject);
|
||||
}
|
||||
|
||||
static int dma_heap_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME);
|
||||
ret = dma_heap_sysfs_setup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME);
|
||||
if (ret)
|
||||
goto err_chrdev;
|
||||
|
||||
dma_heap_class = class_create(THIS_MODULE, DEVNAME);
|
||||
if (IS_ERR(dma_heap_class)) {
|
||||
unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS);
|
||||
return PTR_ERR(dma_heap_class);
|
||||
ret = PTR_ERR(dma_heap_class);
|
||||
goto err_class;
|
||||
}
|
||||
dma_heap_class->devnode = dma_heap_devnode;
|
||||
|
||||
return 0;
|
||||
|
||||
err_class:
|
||||
unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS);
|
||||
err_chrdev:
|
||||
dma_heap_sysfs_teardown();
|
||||
return ret;
|
||||
}
|
||||
subsys_initcall(dma_heap_init);
|
||||
|
||||
@@ -17,6 +17,7 @@ struct dma_heap;
|
||||
/**
|
||||
* struct dma_heap_ops - ops to operate on a given heap
|
||||
* @allocate: allocate dmabuf and return struct dma_buf ptr
|
||||
* @get_pool_size: if heap maintains memory pools, get pool size in bytes
|
||||
*
|
||||
* allocate returns dmabuf on success, ERR_PTR(-errno) on error.
|
||||
*/
|
||||
@@ -25,6 +26,7 @@ struct dma_heap_ops {
|
||||
unsigned long len,
|
||||
unsigned long fd_flags,
|
||||
unsigned long heap_flags);
|
||||
long (*get_pool_size)(struct dma_heap *heap);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user