On 27.06.25 11:49, Sunil Khatri wrote: > add support to add a directory for each client-id > with root at the dri level. Since the clients are > unique and not just related to one single drm device, > so it makes more sense to add all the client based > nodes with root as dri. > > Also create a debugfs file which show the process > information for the client and create a symlink back > to the parent drm device from each client. > > Signed-off-by: Sunil Khatri <sunil.kha...@amd.com>
Reviewed-by: Christian König <christian.koe...@amd.com> > --- > drivers/gpu/drm/drm_debugfs.c | 80 +++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/drm_file.c | 9 ++++ > include/drm/drm_debugfs.h | 11 +++++ > include/drm/drm_file.h | 7 +++ > 4 files changed, 107 insertions(+) > > diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c > index 5807dd64d28a..ee79b694a750 100644 > --- a/drivers/gpu/drm/drm_debugfs.c > +++ b/drivers/gpu/drm/drm_debugfs.c > @@ -305,6 +305,86 @@ void drm_debugfs_remove_accel_root(void) > debugfs_remove(accel_debugfs_root); > } > > +static int drm_debugfs_proc_info_show(struct seq_file *m, void *unused) > +{ > + struct pid *pid; > + struct task_struct *task; > + struct drm_file *file = m->private; > + > + if (!file) > + return -EINVAL; > + > + rcu_read_lock(); > + pid = rcu_dereference(file->pid); > + task = pid_task(pid, PIDTYPE_TGID); > + > + seq_printf(m, "pid: %d\n", task ? task->pid : 0); > + seq_printf(m, "comm: %s\n", task ? task->comm : "Unset"); > + rcu_read_unlock(); > + return 0; > +} > + > +static int drm_debufs_proc_info_open(struct inode *inode, struct file *file) > +{ > + return single_open(file, drm_debugfs_proc_info_show, inode->i_private); > +} > + > +static const struct file_operations drm_debugfs_proc_info_fops = { > + .owner = THIS_MODULE, > + .open = drm_debufs_proc_info_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +/** > + * drm_debugfs_clients_add - Add a per client debugfs directory > + * @file: drm_file for a client > + * > + * Create the debugfs directory for each client. This will be used to > populate > + * driver specific data for each client. > + * > + * Also add the process information debugfs file for each client to tag > + * which client belongs to which process. > + */ > +void drm_debugfs_clients_add(struct drm_file *file) > +{ > + char *client; > + > + client = kasprintf(GFP_KERNEL, "client-%llu", file->client_id); > + if (!client) > + return; > + > + /* Create a debugfs directory for the client in root on drm debugfs */ > + file->debugfs_client = debugfs_create_dir(client, drm_debugfs_root); > + kfree(client); > + > + debugfs_create_file("proc_info", 0444, file->debugfs_client, file, > + &drm_debugfs_proc_info_fops); > + > + client = kasprintf(GFP_KERNEL, "../%s", file->minor->dev->unique); > + if (!client) > + return; > + > + /* Create a link from client_id to the drm device this client id > belongs to */ > + debugfs_create_symlink("device", file->debugfs_client, client); > + kfree(client); > +} > + > +/** > + * drm_debugfs_clients_remove - removes all debugfs directories and files > + * @file: drm_file for a client > + * > + * Removes the debugfs directories recursively from the client directory. > + * > + * There is also a possibility that debugfs files are open while the drm_file > + * is released. > + */ > +void drm_debugfs_clients_remove(struct drm_file *file) > +{ > + debugfs_remove_recursive(file->debugfs_client); > + file->debugfs_client = NULL; > +} > > /** > * drm_debugfs_dev_init - create debugfs directory for the device > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index 06ba6dcbf5ae..3f4c52d00540 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -45,6 +45,7 @@ > #include <drm/drm_file.h> > #include <drm/drm_gem.h> > #include <drm/drm_print.h> > +#include <drm/drm_debugfs.h> > > #include "drm_crtc_internal.h" > #include "drm_internal.h" > @@ -167,6 +168,9 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) > > drm_prime_init_file_private(&file->prime); > > + if (!drm_core_check_feature(dev, DRIVER_COMPUTE_ACCEL)) > + drm_debugfs_clients_add(file); > + > if (dev->driver->open) { > ret = dev->driver->open(dev, file); > if (ret < 0) > @@ -181,6 +185,8 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) > drm_syncobj_release(file); > if (drm_core_check_feature(dev, DRIVER_GEM)) > drm_gem_release(dev, file); > + > + drm_debugfs_clients_remove(file); > put_pid(rcu_access_pointer(file->pid)); > kfree(file); > > @@ -235,6 +241,9 @@ void drm_file_free(struct drm_file *file) > (long)old_encode_dev(file->minor->kdev->devt), > atomic_read(&dev->open_count)); > > + if (!drm_core_check_feature(dev, DRIVER_COMPUTE_ACCEL)) > + drm_debugfs_clients_remove(file); > + > drm_events_release(file); > > if (drm_core_check_feature(dev, DRIVER_MODESET)) { > diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h > index cf06cee4343f..ea8cba94208a 100644 > --- a/include/drm/drm_debugfs.h > +++ b/include/drm/drm_debugfs.h > @@ -153,6 +153,9 @@ void drm_debugfs_add_files(struct drm_device *dev, > > int drm_debugfs_gpuva_info(struct seq_file *m, > struct drm_gpuvm *gpuvm); > + > +void drm_debugfs_clients_add(struct drm_file *file); > +void drm_debugfs_clients_remove(struct drm_file *file); > #else > static inline void drm_debugfs_create_files(const struct drm_info_list > *files, > int count, struct dentry *root, > @@ -181,6 +184,14 @@ static inline int drm_debugfs_gpuva_info(struct seq_file > *m, > { > return 0; > } > + > +static inline void drm_debugfs_clients_add(struct drm_file *file) > +{ > +} > + > +static inline void drm_debugfs_clients_remove(struct drm_file *file) > +{ > +} > #endif > > #endif /* _DRM_DEBUGFS_H_ */ > diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h > index 5c3b2aa3e69d..eab7546aad79 100644 > --- a/include/drm/drm_file.h > +++ b/include/drm/drm_file.h > @@ -400,6 +400,13 @@ struct drm_file { > * @client_name_lock: Protects @client_name. > */ > struct mutex client_name_lock; > + > + /** > + * @debugfs_client: > + * > + * debugfs directory for each client under a drm node. > + */ > + struct dentry *debugfs_client; > }; > > /**