From dc9aad9594b2c8a18b15f6315b2d3ff1ff3dbe50 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 19 Sep 2022 19:35:14 +0900 Subject: [PATCH] drm/v3d: Add gpu_gem_info node via debugfs Add gpu_gem_info node via debugfs of dri debug sysfs for each process with pid/tgid and its gem objects. Same gem object can be opened from multiple processes, so from the gpu_gem_info node, it can print same gem in multiple lines. Ported from the commit dea4ace78ec7 ("drm/vc4: Add gem_info node via debugfs") to v3d. NOTE: From Raspberry Pi 4 board, v3d gpu is card0 and also render node in dri card128, so accessing can be from both nodes. For render fixed node, it is /sys/kernel/debug/dri/128/gpu_gem_info. Also, Raspberry Pi 4 board gives entire gem count and total size with /sys/kernel/debug/dri/128/bo_stats. Change-Id: Ica09a3b92010e15dddc0a7ca117d4544106757f7 Signed-off-by: Seung-Woo Kim --- drivers/gpu/drm/v3d/v3d_bo.c | 43 ++++++++++++++++++++++++ drivers/gpu/drm/v3d/v3d_debugfs.c | 70 +++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/v3d/v3d_drv.c | 2 +- drivers/gpu/drm/v3d/v3d_drv.h | 9 +++++ 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c index 8b52cb2..e9c39c4 100644 --- a/drivers/gpu/drm/v3d/v3d_bo.c +++ b/drivers/gpu/drm/v3d/v3d_bo.c @@ -166,6 +166,46 @@ v3d_prime_import_sg_table(struct drm_device *dev, return obj; } +static void v3d_gem_register_pid(struct drm_file *file) +{ + struct v3d_file_priv *v3d_priv = file->driver_priv; + struct drm_v3d_file_private *pid_priv; + + if (!v3d_priv) + return; + + pid_priv = &v3d_priv->priv; + + if (!pid_priv->pid && !pid_priv->tgid) { + pid_priv->pid = task_pid_nr(current); + pid_priv->tgid = task_tgid_nr(current); + } else { + if (pid_priv->pid != task_pid_nr(current)) + DRM_DEBUG_KMS("wrong pid: %ld, %ld\n", + (unsigned long)pid_priv->pid, + (unsigned long)task_pid_nr(current)); + if (pid_priv->tgid != task_tgid_nr(current)) + DRM_DEBUG_KMS("wrong tgid: %ld, %ld\n", + (unsigned long)pid_priv->tgid, + (unsigned long)task_tgid_nr(current)); + } +} + +int v3d_drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, + uint32_t *handle) +{ + int ret; + + ret = drm_gem_prime_fd_to_handle(dev, file_priv, prime_fd, handle); + if (ret < 0) + return ret; + + v3d_gem_register_pid(file_priv); + + return ret; +} + int v3d_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -185,6 +225,9 @@ int v3d_create_bo_ioctl(struct drm_device *dev, void *data, args->offset = bo->node.start << PAGE_SHIFT; ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); + if (!ret) + v3d_gem_register_pid(file_priv); + drm_gem_object_put(&bo->base.base); return ret; diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c index b7b296b..0700671 100644 --- a/drivers/gpu/drm/v3d/v3d_debugfs.c +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c @@ -237,11 +237,81 @@ static int v3d_measure_clock(struct seq_file *m, void *unused) return 0; } +struct v3d_gem_info_data { + struct drm_file *filp; + struct seq_file *m; +}; + +static int v3d_gem_one_info(int id, void *ptr, void *data) +{ + struct drm_gem_object *obj = (struct drm_gem_object *)ptr; + struct v3d_gem_info_data *gem_info_data = data; + struct v3d_file_priv *v3d_priv = gem_info_data->filp->driver_priv; + struct drm_v3d_file_private *pid_priv = &v3d_priv->priv; + + if (!obj) { + DRM_ERROR("failed to get drm_gem_object\n"); + return -EFAULT; + } + + drm_gem_object_get(obj); + + seq_printf(gem_info_data->m, + "%5d\t%5d\t%4d\t%4d\t\t%4d\t0x%08zx\t0x%x\t%4d\t%4d\t\t" + "%4d\t\t0x%p\t%6d\n", + pid_priv->pid, + pid_priv->tgid, + id, + kref_read(&obj->refcount) - 1, + obj->handle_count, + obj->size, + 0, + 0, + obj->dma_buf ? 1 : 0, + obj->import_attach ? 1 : 0, + obj, + obj->name); + + drm_gem_object_put(obj); + + return 0; +} + +int v3d_debugfs_gem_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *)m->private; + struct drm_minor *minor = node->minor; + struct drm_device *drm_dev = minor->dev; + struct v3d_gem_info_data gem_info_data; + struct drm_file *filp; + + gem_info_data.m = m; + + seq_puts(gem_info_data.m, + "pid\ttgid\thandle\trefcount\thcount\tsize\t\tflags\t" + "pfnmap\texport_to_fd\timport_from_fd\tobj_addr\t\t" + "name\n"); + + mutex_lock(&drm_dev->struct_mutex); + list_for_each_entry(filp, &drm_dev->filelist, lhead) { + gem_info_data.filp = filp; + + spin_lock(&filp->table_lock); + idr_for_each(&filp->object_idr, v3d_gem_one_info, + &gem_info_data); + spin_unlock(&filp->table_lock); + } + mutex_unlock(&drm_dev->struct_mutex); + + return 0; +} + static const struct drm_info_list v3d_debugfs_list[] = { {"v3d_ident", v3d_v3d_debugfs_ident, 0}, {"v3d_regs", v3d_v3d_debugfs_regs, 0}, {"measure_clock", v3d_measure_clock, 0}, {"bo_stats", v3d_debugfs_bo_stats, 0}, + {"gpu_gem_info", v3d_debugfs_gem_info, 0}, }; void diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 3237f47..00cbe84 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -202,7 +202,7 @@ static struct drm_driver v3d_drm_driver = { .gem_create_object = v3d_create_object, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .prime_fd_to_handle = v3d_drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = v3d_prime_import_sg_table, .gem_prime_mmap = drm_gem_prime_mmap, diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 1372e91..231aa57c 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -135,11 +135,17 @@ v3d_has_csd(struct v3d_dev *v3d) #define v3d_to_pdev(v3d) to_platform_device((v3d)->drm.dev) +struct drm_v3d_file_private { + pid_t pid; + pid_t tgid; +}; + /* The per-fd struct, which tracks the MMU mappings. */ struct v3d_file_priv { struct v3d_dev *v3d; struct drm_sched_entity sched_entity[V3D_MAX_QUEUES]; + struct drm_v3d_file_private priv; }; struct v3d_bo { @@ -319,6 +325,9 @@ int v3d_get_bo_offset_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *v3d_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); +int v3d_drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, + uint32_t *handle); /* v3d_debugfs.c */ void v3d_debugfs_init(struct drm_minor *minor); -- 2.7.4