userspace to the forcewake reference count via debugfs.

v2:
use new spin_locks instead of struct_mutex

v3:
spin locks are acquired by the get/put functions now

Signed-off-by: Ben Widawsky <b...@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_debugfs.c |   73 +++++++++++++++++++++++++++++++++++
 1 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index cc3818f..be7dba0 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1181,6 +1181,17 @@ static int i915_gem_framebuffer_info(struct seq_file *m, 
void *data)
        return 0;
 }
 
+static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       seq_printf(m, "forcewake count = %d\n", dev_priv->forcewake_count);
+
+       return 0;
+}
+
 static int
 i915_wedged_open(struct inode *inode,
                 struct file *filp)
@@ -1283,6 +1294,61 @@ static int i915_wedged_create(struct dentry *root, 
struct drm_minor *minor)
        return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
 }
 
+static int i915_forcewake_open(struct inode *inode, struct file *file)
+{
+       struct drm_device *dev = inode->i_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (!IS_GEN6(dev))
+               return 0;
+
+       /*
+        * Paranoid people might say that it's bad that we can potentially hang
+        * userspace spinning on this lock. However, if we cannot acquire this
+        * lock it means that almost certainly the driver has hung, is not
+        * unload-able, and the GPU is not resettable. Therefore hanging here is
+        * probably a minor inconvenience not to be seen my almost every user.
+        */
+       gen6_gt_force_wake_get(dev_priv);
+
+       return 0;
+}
+
+int i915_forcewake_release(struct inode *inode, struct file *file)
+{
+       struct drm_device *dev = inode->i_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (!IS_GEN6(dev))
+               return 0;
+
+       /* see i915_forcewake_open() */
+       gen6_gt_force_wake_put(dev_priv);
+
+       return 0;
+}
+
+static const struct file_operations i915_forcewake_fops = {
+       .owner = THIS_MODULE,
+       .open = i915_forcewake_open,
+       .release = i915_forcewake_release,
+};
+
+static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
+{
+       struct drm_device *dev = minor->dev;
+       struct dentry *ent;
+
+       ent = debugfs_create_file("i915_forcewake_user",
+                                 S_IRWXU,
+                                 root, dev,
+                                 &i915_forcewake_fops);
+       if (IS_ERR(ent))
+               return PTR_ERR(ent);
+
+       return 0;
+}
+
 static struct drm_info_list i915_debugfs_list[] = {
        {"i915_capabilities", i915_capabilities, 0},
        {"i915_gem_objects", i915_gem_object_info, 0},
@@ -1319,6 +1385,7 @@ static struct drm_info_list i915_debugfs_list[] = {
        {"i915_sr_status", i915_sr_status, 0},
        {"i915_opregion", i915_opregion, 0},
        {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
+       {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
@@ -1330,6 +1397,10 @@ int i915_debugfs_init(struct drm_minor *minor)
        if (ret)
                return ret;
 
+       ret = i915_forcewake_create(minor->debugfs_root, minor);
+       if (ret)
+               return ret;
+
        return drm_debugfs_create_files(i915_debugfs_list,
                                        I915_DEBUGFS_ENTRIES,
                                        minor->debugfs_root, minor);
@@ -1339,6 +1410,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
 {
        drm_debugfs_remove_files(i915_debugfs_list,
                                 I915_DEBUGFS_ENTRIES, minor);
+       drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops,
+                                1, minor);
        drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
                                 1, minor);
 }
-- 
1.7.3.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to