summaryrefslogtreecommitdiff
path: root/drivers/staging/android/ion/ion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/android/ion/ion.c')
-rw-r--r--drivers/staging/android/ion/ion.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index dd96ca61a515..4c311b64c50c 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -42,6 +42,7 @@
static struct ion_device *internal_dev;
static int heap_id;
+static atomic_long_t total_heap_bytes;
bool ion_buffer_cached(struct ion_buffer *buffer)
{
@@ -120,6 +121,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
mutex_lock(&dev->buffer_lock);
ion_buffer_add(dev, buffer);
mutex_unlock(&dev->buffer_lock);
+ atomic_long_add(len, &total_heap_bytes);
return buffer;
err1:
@@ -148,6 +150,7 @@ static void _ion_buffer_destroy(struct ion_buffer *buffer)
mutex_lock(&dev->buffer_lock);
rb_erase(&buffer->node, &dev->buffers);
mutex_unlock(&dev->buffer_lock);
+ atomic_long_sub(buffer->size, &total_heap_bytes);
if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
ion_heap_freelist_add(heap, buffer);
@@ -589,6 +592,56 @@ void ion_device_add_heap(struct ion_heap *heap)
}
EXPORT_SYMBOL(ion_device_add_heap);
+static ssize_t
+total_heaps_kb_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ u64 size_in_bytes = atomic_long_read(&total_heap_bytes);
+
+ return sprintf(buf, "%llu\n", div_u64(size_in_bytes, 1024));
+}
+
+static ssize_t
+total_pools_kb_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ u64 size_in_bytes = ion_page_pool_nr_pages() * PAGE_SIZE;
+
+ return sprintf(buf, "%llu\n", div_u64(size_in_bytes, 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;
@@ -605,8 +658,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);
@@ -622,5 +680,11 @@ debugfs_done:
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);