diff --git a/drivers/gpu/arm/bifrost/context/mali_kbase_context.c b/drivers/gpu/arm/bifrost/context/mali_kbase_context.c index 2c7417bd6506..b9a6c2485de8 100644 --- a/drivers/gpu/arm/bifrost/context/mali_kbase_context.c +++ b/drivers/gpu/arm/bifrost/context/mali_kbase_context.c @@ -72,6 +72,75 @@ static struct kbase_process *find_process_node(struct rb_node *node, pid_t tgid) return kprcs; } +static ssize_t kbase_kctx_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct kobj_attribute *kattr = container_of(attr, struct kobj_attribute, attr); + + if (kattr->show) + return kattr->show(kobj, kattr, buf); + + return -EIO; +} + +static ssize_t kbase_total_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct kbase_context *kctx = container_of(kobj, struct kbase_context, kobj); + + return scnprintf(buf, PAGE_SIZE, "%zu\n", kctx->kprcs->total_gpu_pages << PAGE_SHIFT); +} + +static ssize_t kbase_private_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct kbase_context *kctx = container_of(kobj, struct kbase_context, kobj); + struct kbase_process *kprcs = kctx->kprcs; + struct kbase_context *tmp_kctx; + size_t total_pages = 0; + + /* Sum up used_pages from all contexts in the process */ + list_for_each_entry(tmp_kctx, &kprcs->kctx_list, kprcs_link) { + total_pages += atomic_read(&tmp_kctx->used_pages); + } + + return scnprintf(buf, PAGE_SIZE, "%zu\n", total_pages << PAGE_SHIFT); +} + +static struct kobj_attribute kbase_total_gpu_mem_attr = { + .attr = { + .name = "total_gpu_mem", + .mode = 0444, + }, + .show = kbase_total_gpu_mem_show, + .store = NULL, +}; + +static struct kobj_attribute kbase_private_gpu_mem_attr = { + .attr = { + .name = "private_gpu_mem", + .mode = 0444, + }, + .show = kbase_private_gpu_mem_show, + .store = NULL, +}; + +static struct attribute *kbase_kctx_attrs[] = { + &kbase_total_gpu_mem_attr.attr, + &kbase_private_gpu_mem_attr.attr, + NULL, +}; + +static const struct attribute_group kbase_kctx_attr_group = { + .attrs = kbase_kctx_attrs, +}; + +static const struct sysfs_ops kbase_kctx_sysfs_ops = { + .show = kbase_kctx_attr_show, +}; + +static const struct kobj_type kbase_kctx_ktype = { + .sysfs_ops = &kbase_kctx_sysfs_ops, + .default_groups = (const struct attribute_group *[]) { &kbase_kctx_attr_group, NULL }, +}; + /** * kbase_insert_kctx_to_process - Initialise kbase process context. * @@ -100,6 +169,8 @@ static int kbase_insert_kctx_to_process(struct kbase_context *kctx) */ if (!kprcs) { struct rb_node **new = &prcs_root->rb_node, *parent = NULL; + char kctx_name[64]; + int ret = 0; kprcs = kzalloc(sizeof(*kprcs), GFP_KERNEL); if (kprcs == NULL) @@ -109,6 +180,15 @@ static int kbase_insert_kctx_to_process(struct kbase_context *kctx) kprcs->dma_buf_root = RB_ROOT; kprcs->total_gpu_pages = 0; + if (unlikely(!scnprintf(kctx_name, 64, "%d", tgid))) + return -ENOMEM; + + ret = kobject_init_and_add(&kctx->kobj, &kbase_kctx_ktype, kctx->kbdev->kprcs_kobj, kctx_name); + if (ret) { + dev_err(kctx->kbdev->dev, "Failed to create kctx kobject"); + kobject_put(&kctx->kobj); + } + while (*new) { struct kbase_process *prcs_node; @@ -260,6 +340,7 @@ static void kbase_remove_kctx_from_process(struct kbase_context *kctx) * we can remove it from the process rb_tree. */ if (list_empty(&kprcs->kctx_list)) { + kobject_put(&kctx->kobj); rb_erase(&kprcs->kprcs_node, &kctx->kbdev->process_root); /* Add checks, so that the terminating process Should not * hold any gpu_memory. diff --git a/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c b/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c index 0f41b0411faa..46c91c6fcb6c 100644 --- a/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c +++ b/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c @@ -360,8 +360,6 @@ static void kbase_file_delete(struct kbase_file *const kfile) #endif kbase_context_debugfs_term(kctx); - kobject_put(&kctx->kobj); - kbase_destroy_context(kctx); dev_dbg(kbdev->dev, "deleted base context\n"); @@ -626,74 +624,14 @@ static const struct file_operations kbase_force_same_va_fops = { }; #endif /* CONFIG_DEBUG_FS */ -static ssize_t kbase_kctx_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct kobj_attribute *kattr = container_of(attr, struct kobj_attribute, attr); - - if (kattr->show) - return kattr->show(kobj, kattr, buf); - - return -EIO; -} - -static ssize_t kbase_total_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -{ - struct kbase_context *kctx = container_of(kobj, struct kbase_context, kobj); - - return scnprintf(buf, PAGE_SIZE, "%zu\n", kctx->kprcs->total_gpu_pages << PAGE_SHIFT); -} - -static ssize_t kbase_private_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -{ - struct kbase_context *kctx = container_of(kobj, struct kbase_context, kobj); - - return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&kctx->used_pages) << PAGE_SHIFT); -} - -static struct kobj_attribute kbase_total_gpu_mem_attr = { - .attr = { - .name = "total_gpu_mem", - .mode = 0444, - }, - .show = kbase_total_gpu_mem_show, - .store = NULL, -}; - -static struct kobj_attribute kbase_private_gpu_mem_attr = { - .attr = { - .name = "private_gpu_mem", - .mode = 0444, - }, - .show = kbase_private_gpu_mem_show, - .store = NULL, -}; - -static struct attribute *kbase_kctx_attrs[] = { - &kbase_total_gpu_mem_attr.attr, - &kbase_private_gpu_mem_attr.attr, - NULL, -}; - -static const struct attribute_group kbase_kctx_attr_group = { - .attrs = kbase_kctx_attrs, -}; - -static const struct sysfs_ops kbase_kctx_sysfs_ops = { - .show = kbase_kctx_attr_show, -}; - -static const struct kobj_type kbase_kctx_ktype = { - .sysfs_ops = &kbase_kctx_sysfs_ops, - .default_groups = (const struct attribute_group *[]) { &kbase_kctx_attr_group, NULL }, -}; - static int kbase_file_create_kctx(struct kbase_file *const kfile, base_context_create_flags const flags) { struct kbase_device *kbdev = NULL; struct kbase_context *kctx = NULL; +#if IS_ENABLED(CONFIG_DEBUG_FS) char kctx_name[64]; - int ret = 0; +#endif if (WARN_ON(!kfile)) return -EINVAL; @@ -738,12 +676,6 @@ static int kbase_file_create_kctx(struct kbase_file *const kfile, } #endif /* CONFIG_DEBUG_FS */ - ret = kobject_init_and_add(&kctx->kobj, &kbase_kctx_ktype, kbdev->kprcs_kobj, kctx_name); - if (ret) { - dev_err(kbdev->dev, "Failed to create kctx kobject"); - kobject_put(&kctx->kobj); - } - dev_dbg(kbdev->dev, "created base context\n"); kfile->kctx = kctx;