From 3029fcd04ed8fd30bdf23cce18c93551537051a5 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 23 Mar 2017 15:11:01 +0900 Subject: [PATCH] drm/vc4: add gem_info node via debugfs The memps requires gem_info with gem_names to analyze graphics shared memory, so this patch adds gem_info node via debugfs interface. Let's save pid/tgid in private file data only once when gem object is created or prime_fd is imported and use them on gem_info. This is to solve the wrong pid problem of gem_info created as different processes share fd of drm device node. Change-Id: Iaac2ccd63e124dd11a894f0e88ddbb533750f3d4 Signed-off-by: Joonyoung Shim [sw0312.kim: fix wrong printing format in gem_info debugfs for 32bit arm build with %zx] Signed-off-by: Seung-Woo Kim --- drivers/gpu/drm/vc4/vc4_bo.c | 113 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 9 +++ 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 8dcce71..87bdab9 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -99,6 +99,76 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) return 0; } + +struct vc4_gem_info_data { + struct drm_file *filp; + struct seq_file *m; +}; + +static int vc4_gem_one_info(int id, void *ptr, void *data) +{ + struct drm_gem_object *obj = (struct drm_gem_object *)ptr; + struct vc4_gem_info_data *gem_info_data = data; + struct drm_vc4_file_private *file_priv = + gem_info_data->filp->driver_priv; + + if (!obj) { + DRM_ERROR("failed to get drm_gem_object\n"); + return -EFAULT; + } + + drm_gem_object_reference(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", + file_priv->pid, + file_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_unreference(obj); + + return 0; +} + +int vc4_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 vc4_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, vc4_gem_one_info, + &gem_info_data); + spin_unlock(&filp->table_lock); + } + mutex_unlock(&drm_dev->struct_mutex); + + return 0; +} + #endif /* Takes ownership of *name and returns the appropriate slot for it in @@ -498,6 +568,25 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, return bo; } +static void vc4_gem_register_pid(struct drm_file *file_priv) +{ + struct drm_vc4_file_private *driver_priv = file_priv->driver_priv; + + if (!driver_priv->pid && !driver_priv->tgid) { + driver_priv->pid = task_pid_nr(current); + driver_priv->tgid = task_tgid_nr(current); + } else { + if (driver_priv->pid != task_pid_nr(current)) + DRM_DEBUG_KMS("wrong pid: %ld, %ld\n", + (unsigned long)driver_priv->pid, + (unsigned long)task_pid_nr(current)); + if (driver_priv->tgid != task_tgid_nr(current)) + DRM_DEBUG_KMS("wrong tgid: %ld, %ld\n", + (unsigned long)driver_priv->tgid, + (unsigned long)task_tgid_nr(current)); + } +} + int vc4_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) @@ -521,6 +610,9 @@ int vc4_dumb_create(struct drm_file *file_priv, ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); drm_gem_object_put_unlocked(&bo->base.base); + if (!ret) + vc4_gem_register_pid(file_priv); + return ret; } @@ -737,6 +829,21 @@ vm_fault_t vc4_fault(struct vm_fault *vmf) return VM_FAULT_SIGBUS; } +int vc4_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) + goto out; + + vc4_gem_register_pid(file_priv); + +out: + return ret; +} + int vc4_mmap(struct file *filp, struct vm_area_struct *vma) { struct drm_gem_object *gem_obj; @@ -854,6 +961,9 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); drm_gem_object_put_unlocked(&bo->base.base); + if (!ret) + vc4_gem_register_pid(file_priv); + return ret; } @@ -929,6 +1039,9 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, */ ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); + if (!ret) + vc4_gem_register_pid(file_priv); + fail: drm_gem_object_put_unlocked(&bo->base.base); diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c index 7a0003d..55ce842 100644 --- a/drivers/gpu/drm/vc4/vc4_debugfs.c +++ b/drivers/gpu/drm/vc4/vc4_debugfs.c @@ -28,6 +28,7 @@ static const struct drm_info_list vc4_debugfs_list[] = { {"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2}, {"v3d_ident", vc4_v3d_debugfs_ident, 0}, {"v3d_regs", vc4_v3d_debugfs_regs, 0}, + {"gem_info", vc4_debugfs_gem_info, 0}, }; #define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 5b2f60b..2cbba4d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -198,7 +198,7 @@ static struct drm_driver vc4_drm_driver = { .gem_vm_ops = &vc4_vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .prime_fd_to_handle = vc4_drm_gem_prime_fd_to_handle, .gem_prime_import = drm_gem_prime_import, .gem_prime_export = vc4_prime_export, .gem_prime_res_obj = vc4_prime_res_obj, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index b4c3bc9..d9436491 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -812,6 +812,15 @@ bool vc4_check_tex_size(struct vc4_exec_info *exec, struct vc4_validated_shader_info * vc4_validate_shader(struct drm_gem_cma_object *shader_obj); +struct drm_vc4_file_private { + pid_t pid; + pid_t tgid; +}; + +int vc4_debugfs_gem_info(struct seq_file *m, void *data); +int vc4_drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, uint32_t *handle); + /* vc4_perfmon.c */ void vc4_perfmon_get(struct vc4_perfmon *perfmon); void vc4_perfmon_put(struct vc4_perfmon *perfmon); -- 2.7.4