summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_debugfs.c')
-rw-r--r--drivers/gpu/drm/drm_debugfs.c188
1 files changed, 87 insertions, 101 deletions
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 2de43ff3ce0a..f291fb4b359f 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -40,7 +40,7 @@
#include <drm/drm_file.h>
#include <drm/drm_gem.h>
#include <drm/drm_managed.h>
-#include <drm/drm_gpuva_mgr.h>
+#include <drm/drm_gpuvm.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
@@ -92,15 +92,17 @@ static int drm_clients_info(struct seq_file *m, void *data)
*/
mutex_lock(&dev->filelist_mutex);
list_for_each_entry_reverse(priv, &dev->filelist, lhead) {
- struct task_struct *task;
bool is_current_master = drm_is_current_master(priv);
+ struct task_struct *task;
+ struct pid *pid;
- rcu_read_lock(); /* locks pid_task()->comm */
- task = pid_task(priv->pid, PIDTYPE_TGID);
+ rcu_read_lock(); /* Locks priv->pid and pid_task()->comm! */
+ pid = rcu_dereference(priv->pid);
+ task = pid_task(pid, PIDTYPE_TGID);
uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID;
seq_printf(m, "%20s %5d %3d %c %c %5d %10u\n",
task ? task->comm : "<unknown>",
- pid_vnr(priv->pid),
+ pid_vnr(pid),
priv->minor->index,
is_current_master ? 'y' : 'n',
priv->authenticated ? 'y' : 'n',
@@ -150,6 +152,9 @@ static int drm_debugfs_open(struct inode *inode, struct file *file)
{
struct drm_info_node *node = inode->i_private;
+ if (!device_is_registered(node->minor->kdev))
+ return -ENODEV;
+
return single_open(file, node->info_ent->show, node);
}
@@ -157,6 +162,10 @@ static int drm_debugfs_entry_open(struct inode *inode, struct file *file)
{
struct drm_debugfs_entry *entry = inode->i_private;
struct drm_debugfs_info *node = &entry->file;
+ struct drm_minor *minor = entry->dev->primary ?: entry->dev->accel;
+
+ if (!device_is_registered(minor->kdev))
+ return -ENODEV;
return single_open(file, node->show, entry);
}
@@ -180,31 +189,31 @@ static const struct file_operations drm_debugfs_fops = {
/**
* drm_debugfs_gpuva_info - dump the given DRM GPU VA space
* @m: pointer to the &seq_file to write
- * @mgr: the &drm_gpuva_manager representing the GPU VA space
+ * @gpuvm: the &drm_gpuvm representing the GPU VA space
*
* Dumps the GPU VA mappings of a given DRM GPU VA manager.
*
* For each DRM GPU VA space drivers should call this function from their
* &drm_info_list's show callback.
*
- * Returns: 0 on success, -ENODEV if the &mgr is not initialized
+ * Returns: 0 on success, -ENODEV if the &gpuvm is not initialized
*/
int drm_debugfs_gpuva_info(struct seq_file *m,
- struct drm_gpuva_manager *mgr)
+ struct drm_gpuvm *gpuvm)
{
- struct drm_gpuva *va, *kva = &mgr->kernel_alloc_node;
+ struct drm_gpuva *va, *kva = &gpuvm->kernel_alloc_node;
- if (!mgr->name)
+ if (!gpuvm->name)
return -ENODEV;
seq_printf(m, "DRM GPU VA space (%s) [0x%016llx;0x%016llx]\n",
- mgr->name, mgr->mm_start, mgr->mm_start + mgr->mm_range);
+ gpuvm->name, gpuvm->mm_start, gpuvm->mm_start + gpuvm->mm_range);
seq_printf(m, "Kernel reserved node [0x%016llx;0x%016llx]\n",
kva->va.addr, kva->va.addr + kva->va.range);
seq_puts(m, "\n");
seq_puts(m, " VAs | start | range | end | object | object offset\n");
seq_puts(m, "-------------------------------------------------------------------------------------------------------------\n");
- drm_gpuva_for_each_va(va, mgr) {
+ drm_gpuvm_for_each_va(va, gpuvm) {
if (unlikely(va == kva))
continue;
@@ -227,7 +236,7 @@ EXPORT_SYMBOL(drm_debugfs_gpuva_info);
*
* Create a given set of debugfs files represented by an array of
* &struct drm_info_list in the given root directory. These files will be removed
- * automatically on drm_debugfs_cleanup().
+ * automatically on drm_debugfs_dev_fini().
*/
void drm_debugfs_create_files(const struct drm_info_list *files, int count,
struct dentry *root, struct drm_minor *minor)
@@ -242,7 +251,7 @@ void drm_debugfs_create_files(const struct drm_info_list *files, int count,
if (features && !drm_core_check_all_features(dev, features))
continue;
- tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
+ tmp = drmm_kzalloc(dev, sizeof(*tmp), GFP_KERNEL);
if (tmp == NULL)
continue;
@@ -251,111 +260,89 @@ void drm_debugfs_create_files(const struct drm_info_list *files, int count,
0444, root, tmp,
&drm_debugfs_fops);
tmp->info_ent = &files[i];
-
- mutex_lock(&minor->debugfs_lock);
- list_add(&tmp->list, &minor->debugfs_list);
- mutex_unlock(&minor->debugfs_lock);
}
}
EXPORT_SYMBOL(drm_debugfs_create_files);
-int drm_debugfs_init(struct drm_minor *minor, int minor_id,
- struct dentry *root)
+int drm_debugfs_remove_files(const struct drm_info_list *files, int count,
+ struct dentry *root, struct drm_minor *minor)
{
- struct drm_device *dev = minor->dev;
- struct drm_debugfs_entry *entry, *tmp;
- char name[64];
-
- INIT_LIST_HEAD(&minor->debugfs_list);
- mutex_init(&minor->debugfs_lock);
- sprintf(name, "%d", minor_id);
- minor->debugfs_root = debugfs_create_dir(name, root);
-
- drm_debugfs_add_files(minor->dev, drm_debugfs_list, DRM_DEBUGFS_ENTRIES);
-
- if (drm_drv_uses_atomic_modeset(dev)) {
- drm_atomic_debugfs_init(minor);
- drm_bridge_debugfs_init(minor);
- }
-
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- drm_framebuffer_debugfs_init(minor);
+ int i;
- drm_client_debugfs_init(minor);
- }
+ for (i = 0; i < count; i++) {
+ struct dentry *dent = debugfs_lookup(files[i].name, root);
- if (dev->driver->debugfs_init)
- dev->driver->debugfs_init(minor);
+ if (!dent)
+ continue;
- list_for_each_entry_safe(entry, tmp, &dev->debugfs_list, list) {
- debugfs_create_file(entry->file.name, 0444,
- minor->debugfs_root, entry, &drm_debugfs_entry_fops);
- list_del(&entry->list);
+ drmm_kfree(minor->dev, d_inode(dent)->i_private);
+ debugfs_remove(dent);
}
-
return 0;
}
+EXPORT_SYMBOL(drm_debugfs_remove_files);
-void drm_debugfs_late_register(struct drm_device *dev)
+/**
+ * drm_debugfs_dev_init - create debugfs directory for the device
+ * @dev: the device which we want to create the directory for
+ * @root: the parent directory depending on the device type
+ *
+ * Creates the debugfs directory for the device under the given root directory.
+ */
+void drm_debugfs_dev_init(struct drm_device *dev, struct dentry *root)
{
- struct drm_minor *minor = dev->primary;
- struct drm_debugfs_entry *entry, *tmp;
-
- if (!minor)
- return;
-
- list_for_each_entry_safe(entry, tmp, &dev->debugfs_list, list) {
- debugfs_create_file(entry->file.name, 0444,
- minor->debugfs_root, entry, &drm_debugfs_entry_fops);
- list_del(&entry->list);
- }
+ dev->debugfs_root = debugfs_create_dir(dev->unique, root);
}
-int drm_debugfs_remove_files(const struct drm_info_list *files, int count,
- struct drm_minor *minor)
+/**
+ * drm_debugfs_dev_fini - cleanup debugfs directory
+ * @dev: the device to cleanup the debugfs stuff
+ *
+ * Remove the debugfs directory, might be called multiple times.
+ */
+void drm_debugfs_dev_fini(struct drm_device *dev)
{
- struct list_head *pos, *q;
- struct drm_info_node *tmp;
- int i;
-
- mutex_lock(&minor->debugfs_lock);
- for (i = 0; i < count; i++) {
- list_for_each_safe(pos, q, &minor->debugfs_list) {
- tmp = list_entry(pos, struct drm_info_node, list);
- if (tmp->info_ent == &files[i]) {
- debugfs_remove(tmp->dent);
- list_del(pos);
- kfree(tmp);
- }
- }
- }
- mutex_unlock(&minor->debugfs_lock);
- return 0;
+ debugfs_remove_recursive(dev->debugfs_root);
+ dev->debugfs_root = NULL;
}
-EXPORT_SYMBOL(drm_debugfs_remove_files);
-static void drm_debugfs_remove_all_files(struct drm_minor *minor)
+void drm_debugfs_dev_register(struct drm_device *dev)
{
- struct drm_info_node *node, *tmp;
+ drm_debugfs_add_files(dev, drm_debugfs_list, DRM_DEBUGFS_ENTRIES);
- mutex_lock(&minor->debugfs_lock);
- list_for_each_entry_safe(node, tmp, &minor->debugfs_list, list) {
- debugfs_remove(node->dent);
- list_del(&node->list);
- kfree(node);
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ drm_framebuffer_debugfs_init(dev);
+ drm_client_debugfs_init(dev);
+ }
+ if (drm_drv_uses_atomic_modeset(dev)) {
+ drm_atomic_debugfs_init(dev);
+ drm_bridge_debugfs_init(dev);
}
- mutex_unlock(&minor->debugfs_lock);
}
-void drm_debugfs_cleanup(struct drm_minor *minor)
+int drm_debugfs_register(struct drm_minor *minor, int minor_id,
+ struct dentry *root)
{
- if (!minor->debugfs_root)
- return;
+ struct drm_device *dev = minor->dev;
+ char name[64];
+
+ sprintf(name, "%d", minor_id);
+ minor->debugfs_symlink = debugfs_create_symlink(name, root,
+ dev->unique);
+
+ /* TODO: Only for compatibility with drivers */
+ minor->debugfs_root = dev->debugfs_root;
- drm_debugfs_remove_all_files(minor);
+ if (dev->driver->debugfs_init && dev->render != minor)
+ dev->driver->debugfs_init(minor);
- debugfs_remove_recursive(minor->debugfs_root);
- minor->debugfs_root = NULL;
+ return 0;
+}
+
+void drm_debugfs_unregister(struct drm_minor *minor)
+{
+ debugfs_remove(minor->debugfs_symlink);
+ minor->debugfs_symlink = NULL;
}
/**
@@ -381,9 +368,8 @@ void drm_debugfs_add_file(struct drm_device *dev, const char *name,
entry->file.data = data;
entry->dev = dev;
- mutex_lock(&dev->debugfs_mutex);
- list_add(&entry->list, &dev->debugfs_list);
- mutex_unlock(&dev->debugfs_mutex);
+ debugfs_create_file(name, 0444, dev->debugfs_root, entry,
+ &drm_debugfs_entry_fops);
}
EXPORT_SYMBOL(drm_debugfs_add_file);
@@ -540,13 +526,13 @@ static const struct file_operations drm_connector_fops = {
void drm_debugfs_connector_add(struct drm_connector *connector)
{
- struct drm_minor *minor = connector->dev->primary;
+ struct drm_device *dev = connector->dev;
struct dentry *root;
- if (!minor->debugfs_root)
+ if (!dev->debugfs_root)
return;
- root = debugfs_create_dir(connector->name, minor->debugfs_root);
+ root = debugfs_create_dir(connector->name, dev->debugfs_root);
connector->debugfs_entry = root;
/* force */
@@ -581,7 +567,7 @@ void drm_debugfs_connector_remove(struct drm_connector *connector)
void drm_debugfs_crtc_add(struct drm_crtc *crtc)
{
- struct drm_minor *minor = crtc->dev->primary;
+ struct drm_device *dev = crtc->dev;
struct dentry *root;
char *name;
@@ -589,7 +575,7 @@ void drm_debugfs_crtc_add(struct drm_crtc *crtc)
if (!name)
return;
- root = debugfs_create_dir(name, minor->debugfs_root);
+ root = debugfs_create_dir(name, dev->debugfs_root);
kfree(name);
crtc->debugfs_entry = root;