From a8c41d35c29ebea0768edb54ac7569c349599d0b Mon Sep 17 00:00:00 2001 From: Ankit Goyal Date: Tue, 13 Jul 2021 17:21:51 +0800 Subject: [PATCH] mali_kbase: platform: Add per-process and global sysfs nodes for GPU mem usage Bug: 191966412 Signed-off-by: Ankit Goyal Change-Id: Id47feadaf9da7ef8e22494ab64e6263d7f87213c Signed-off-by: nishant6342 --- .../arm/midgard/context/mali_kbase_context.c | 48 +++++++++++++++++++ .../gpu/arm/midgard/mali_kbase_core_linux.c | 37 ++++++++++++++ .../drivers/gpu/arm/midgard/mali_kbase_defs.h | 7 +++ .../arm/midgard/context/mali_kbase_context.c | 48 +++++++++++++++++++ .../gpu/arm/midgard/mali_kbase_core_linux.c | 37 ++++++++++++++ .../drivers/gpu/arm/midgard/mali_kbase_defs.h | 6 +++ 6 files changed, 183 insertions(+) diff --git a/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/context/mali_kbase_context.c b/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/context/mali_kbase_context.c index 2a6e3811a8c2..5a666e5497b6 100755 --- a/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/context/mali_kbase_context.c +++ b/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/context/mali_kbase_context.c @@ -35,6 +35,48 @@ #include #include +#define to_kprcs(kobj) container_of(kobj, struct kbase_process, kobj) + +static void kbase_kprcs_release(struct kobject *kobj) +{ + // Nothing to release +} + +static ssize_t total_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct kbase_process *kprcs = to_kprcs(kobj); + if (WARN_ON(!kprcs)) + return 0; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kprcs->total_gpu_pages << PAGE_SHIFT); +} +static struct kobj_attribute total_gpu_mem_attr = __ATTR_RO(total_gpu_mem); + +static ssize_t dma_buf_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct kbase_process *kprcs = to_kprcs(kobj); + if (WARN_ON(!kprcs)) + return 0; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kprcs->dma_buf_pages << PAGE_SHIFT); +} +static struct kobj_attribute dma_buf_gpu_mem_attr = __ATTR_RO(dma_buf_gpu_mem); + +static struct attribute *kprcs_attrs[] = { + &total_gpu_mem_attr.attr, + &dma_buf_gpu_mem_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(kprcs); + +static struct kobj_type kprcs_ktype = { + .release = kbase_kprcs_release, + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = kprcs_groups, +}; + /** * find_process_node - Used to traverse the process rb_tree to find if * process exists already in process rb_tree. @@ -103,6 +145,10 @@ static int kbase_insert_kctx_to_process(struct kbase_context *kctx) kprcs->dma_buf_root = RB_ROOT; kprcs->total_gpu_pages = 0; kprcs->dma_buf_pages = 0; + WARN_ON(kobject_init_and_add( + &kprcs->kobj, &kprcs_ktype, + kctx->kbdev->proc_sysfs_node, + "%d", tgid)); while (*new) { struct kbase_process *prcs_node; @@ -240,6 +286,8 @@ static void kbase_remove_kctx_from_process(struct kbase_context *kctx) */ WARN_ON(kprcs->total_gpu_pages); WARN_ON(!RB_EMPTY_ROOT(&kprcs->dma_buf_root)); + kobject_del(&kprcs->kobj); + kobject_put(&kprcs->kobj); kfree(kprcs); } } diff --git a/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_core_linux.c index 422f8d181aa2..a5a2b7f2da58 100755 --- a/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +++ b/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_core_linux.c @@ -4288,6 +4288,36 @@ static struct attribute *kbase_scheduling_attrs[] = { NULL }; +static ssize_t total_gpu_mem_show( + struct device *dev, + struct device_attribute *attr, + char *const buf) +{ + struct kbase_device *kbdev; + kbdev = to_kbase_device(dev); + if (!kbdev) + return -ENODEV; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kbdev->total_gpu_pages << PAGE_SHIFT); +} +static DEVICE_ATTR_RO(total_gpu_mem); + +static ssize_t dma_buf_gpu_mem_show( + struct device *dev, + struct device_attribute *attr, + char *const buf) +{ + struct kbase_device *kbdev; + kbdev = to_kbase_device(dev); + if (!kbdev) + return -ENODEV; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kbdev->dma_buf_pages << PAGE_SHIFT); +} +static DEVICE_ATTR_RO(dma_buf_gpu_mem); + static struct attribute *kbase_attrs[] = { #ifdef CONFIG_MALI_DEBUG &dev_attr_debug_command.attr, @@ -4307,6 +4337,8 @@ static struct attribute *kbase_attrs[] = { &dev_attr_lp_mem_pool_size.attr, &dev_attr_lp_mem_pool_max_size.attr, &dev_attr_js_ctx_scheduling_mode.attr, + &dev_attr_total_gpu_mem.attr, + &dev_attr_dma_buf_gpu_mem.attr, NULL }; @@ -4342,6 +4374,9 @@ int kbase_sysfs_init(struct kbase_device *kbdev) } } + kbdev->proc_sysfs_node = kobject_create_and_add("kprcs", + &kbdev->dev->kobj); + return err; } @@ -4349,6 +4384,8 @@ void kbase_sysfs_term(struct kbase_device *kbdev) { sysfs_remove_group(&kbdev->dev->kobj, &kbase_scheduling_attr_group); sysfs_remove_group(&kbdev->dev->kobj, &kbase_attr_group); + kobject_del(kbdev->proc_sysfs_node); + kobject_put(kbdev->proc_sysfs_node); put_device(kbdev->dev); } diff --git a/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_defs.h b/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_defs.h index 7ac599c70ec9..65f7fd4e15d9 100755 --- a/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_defs.h +++ b/drivers/gpu/mediatek/gpu_mali/mali_bifrost/mali-r25p0/drivers/gpu/arm/midgard/mali_kbase_defs.h @@ -657,6 +657,8 @@ struct kbase_devfreq_queue_info { * Used to ensure that pages of allocation are accounted * only once for the process, even if the allocation gets * imported multiple times for the process. + * @kobj: Links to the per-process sysfs node + * &kbase_device.proc_sysfs_node. */ struct kbase_process { pid_t tgid; @@ -666,6 +668,8 @@ struct kbase_process { struct rb_node kprcs_node; struct rb_root dma_buf_root; + + struct kobject kobj; }; /** @@ -930,6 +934,7 @@ struct kbase_process { * @gpu_mem_usage_lock: This spinlock should be held while accounting * @total_gpu_pages for both native and dma-buf imported * allocations. + * @proc_sysfs_node: Sysfs directory node to store per-process stats. */ struct kbase_device { u32 hw_quirks_sc; @@ -1191,6 +1196,8 @@ struct kbase_device { struct job_status_qos job_status_addr; struct v1_data* v1; #endif + + struct kobject *proc_sysfs_node; }; /** diff --git a/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/context/mali_kbase_context.c b/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/context/mali_kbase_context.c index caaf9cf35189..bcc843eb515b 100644 --- a/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/context/mali_kbase_context.c +++ b/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/context/mali_kbase_context.c @@ -32,6 +32,48 @@ #include #include +#define to_kprcs(kobj) container_of(kobj, struct kbase_process, kobj) + +static void kbase_kprcs_release(struct kobject *kobj) +{ + // Nothing to release +} + +static ssize_t total_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct kbase_process *kprcs = to_kprcs(kobj); + if (WARN_ON(!kprcs)) + return 0; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kprcs->total_gpu_pages << PAGE_SHIFT); +} +static struct kobj_attribute total_gpu_mem_attr = __ATTR_RO(total_gpu_mem); + +static ssize_t dma_buf_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct kbase_process *kprcs = to_kprcs(kobj); + if (WARN_ON(!kprcs)) + return 0; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kprcs->dma_buf_pages << PAGE_SHIFT); +} +static struct kobj_attribute dma_buf_gpu_mem_attr = __ATTR_RO(dma_buf_gpu_mem); + +static struct attribute *kprcs_attrs[] = { + &total_gpu_mem_attr.attr, + &dma_buf_gpu_mem_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(kprcs); + +static struct kobj_type kprcs_ktype = { + .release = kbase_kprcs_release, + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = kprcs_groups, +}; + /** * find_process_node - Used to traverse the process rb_tree to find if * process exists already in process rb_tree. @@ -100,6 +142,10 @@ static int kbase_insert_kctx_to_process(struct kbase_context *kctx) kprcs->dma_buf_root = RB_ROOT; kprcs->total_gpu_pages = 0; kprcs->dma_buf_pages = 0; + WARN_ON(kobject_init_and_add( + &kprcs->kobj, &kprcs_ktype, + kctx->kbdev->proc_sysfs_node, + "%d", tgid)); while (*new) { struct kbase_process *prcs_node; @@ -237,6 +283,8 @@ static void kbase_remove_kctx_from_process(struct kbase_context *kctx) */ WARN_ON(kprcs->total_gpu_pages); WARN_ON(!RB_EMPTY_ROOT(&kprcs->dma_buf_root)); + kobject_del(&kprcs->kobj); + kobject_put(&kprcs->kobj); kfree(kprcs); } } diff --git a/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_core_linux.c index d7759f7b0a78..66ec9a2188b6 100644 --- a/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +++ b/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_core_linux.c @@ -5086,6 +5086,36 @@ static struct attribute *kbase_scheduling_attrs[] = { NULL }; +static ssize_t total_gpu_mem_show( + struct device *dev, + struct device_attribute *attr, + char *const buf) +{ + struct kbase_device *kbdev; + kbdev = to_kbase_device(dev); + if (!kbdev) + return -ENODEV; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kbdev->total_gpu_pages << PAGE_SHIFT); +} +static DEVICE_ATTR_RO(total_gpu_mem); + +static ssize_t dma_buf_gpu_mem_show( + struct device *dev, + struct device_attribute *attr, + char *const buf) +{ + struct kbase_device *kbdev; + kbdev = to_kbase_device(dev); + if (!kbdev) + return -ENODEV; + + return sysfs_emit(buf, "%lu\n", + (unsigned long) kbdev->dma_buf_pages << PAGE_SHIFT); +} +static DEVICE_ATTR_RO(dma_buf_gpu_mem); + static struct attribute *kbase_attrs[] = { #ifdef CONFIG_MALI_DEBUG &dev_attr_debug_command.attr, @@ -5119,6 +5149,8 @@ static struct attribute *kbase_attrs[] = { #if !MALI_USE_CSF &dev_attr_js_ctx_scheduling_mode.attr, #endif /* !MALI_USE_CSF */ + &dev_attr_total_gpu_mem.attr, + &dev_attr_dma_buf_gpu_mem.attr, NULL }; @@ -5180,6 +5212,9 @@ int kbase_sysfs_init(struct kbase_device *kbdev) &kbase_attr_group); } + kbdev->proc_sysfs_node = kobject_create_and_add("kprcs", + &kbdev->dev->kobj); + return err; } @@ -5188,6 +5223,8 @@ void kbase_sysfs_term(struct kbase_device *kbdev) sysfs_remove_group(&kbdev->dev->kobj, &kbase_mempool_attr_group); sysfs_remove_group(&kbdev->dev->kobj, &kbase_scheduling_attr_group); sysfs_remove_group(&kbdev->dev->kobj, &kbase_attr_group); + kobject_del(kbdev->proc_sysfs_node); + kobject_put(kbdev->proc_sysfs_node); put_device(kbdev->dev); } diff --git a/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_defs.h b/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_defs.h index a3e86f8d5623..2bba1e19bef5 100644 --- a/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_defs.h +++ b/drivers/gpu/mediatek/gpu_mali/mali_valhall/mali-r32p1/drivers/gpu/arm/midgard/mali_kbase_defs.h @@ -639,6 +639,8 @@ struct kbase_devfreq_queue_info { * Used to ensure that pages of allocation are accounted * only once for the process, even if the allocation gets * imported multiple times for the process. + * @kobj: Links to the per-process sysfs node + * &kbase_device.proc_sysfs_node. */ struct kbase_process { pid_t tgid; @@ -648,6 +650,8 @@ struct kbase_process { struct rb_node kprcs_node; struct rb_root dma_buf_root; + + struct kobject kobj; }; /** @@ -958,6 +962,7 @@ struct kbase_process { * @pcm_dev: The priority control manager device. * @oom_notifier_block: notifier_block containing kernel-registered out-of- * memory handler. + * @proc_sysfs_node: Sysfs directory node to store per-process stats. */ struct kbase_device { u32 hw_quirks_sc; @@ -1220,6 +1225,7 @@ struct kbase_device { struct job_status_qos job_status_addr; struct v1_data* v1; #endif + struct kobject *proc_sysfs_node; }; /**