Provide a way for userspace shader debugger to notify the kernel that it will be debugging. This interface does two things, provides a way for the kernel to prepare for debugging, and act as a lock between concurrent debugging (of course none of this is enforced). --- drivers/gpu/drm/i915/i915_debugfs.c | 73 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 6 +++ drivers/gpu/drm/i915/i915_irq.c | 2 +- 3 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4d46441..ab6e2a2 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1395,6 +1395,74 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); } +static int i915_debugger_open(struct inode *inode, struct file *file) +{ + struct drm_device *dev = inode->i_private; + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + if (atomic_add_return(1, &dev_priv->debug.debugging) != 1) { + atomic_dec(&dev_priv->debug.debugging); + return -EBUSY; + } + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) { + atomic_dec(&dev_priv->debug.debugging); + return ret; + } + + del_timer_sync(&dev_priv->hangcheck_timer); + dev_priv->hangcheck_disabled = true; + + dev_priv->debug.debugger = current; + + mutex_unlock(&dev->struct_mutex); + return 0; +} + +static int i915_debugger_release(struct inode *inode, struct file *file) +{ + struct drm_device *dev = inode->i_private; + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev->struct_mutex); + + if (WARN_ON(dev_priv->debug.debugger != current)) + return -ENXIO; + + WARN_ON(atomic_dec_and_test(&dev_priv->debug.debugging) == 0); + + dev_priv->debug.debugger = NULL; + dev_priv->hangcheck_disabled = false; + mutex_unlock(&dev->struct_mutex); + return 0; +} + +static const struct file_operations i915_debugger_fops = { + .owner = THIS_MODULE, + .open = i915_debugger_open, + .release = i915_debugger_release, +}; + +static int i915_debugger_create(struct dentry *root, struct drm_minor *minor) +{ + struct drm_device *dev = minor->dev; + struct dentry *ent; + + ent = debugfs_create_file("i915_debugger", + S_IRUSR, + root, dev, + &i915_debugger_fops); + if (IS_ERR(ent)) + return PTR_ERR(ent); + + return drm_add_fake_info_node(minor, ent, &i915_debugger_fops); + + return 0; +} + + static struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0}, {"i915_gem_objects", i915_gem_object_info, 0}, @@ -1448,6 +1516,9 @@ int i915_debugfs_init(struct drm_minor *minor) if (ret) return ret; + ret = i915_debugger_create(minor->debugfs_root, minor); + if (ret) + return ret; return drm_debugfs_create_files(i915_debugfs_list, I915_DEBUGFS_ENTRIES, minor->debugfs_root, minor); @@ -1457,6 +1528,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_debugger_fops, + 1, 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, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 05f82a7..a4418eb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -720,6 +720,12 @@ typedef struct drm_i915_private { struct drm_property *force_audio_property; atomic_t forcewake_count; + + struct { + atomic_t debugging; + struct task_struct *debugger; + } debug; + } drm_i915_private_t; enum i915_cache_level { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index af72412..ca8ec0f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1723,7 +1723,7 @@ void i915_hangcheck_elapsed(unsigned long data) } repeat: - BUG_ON(dev_priv->hangcheck_disabled); + WARN_ON(dev_priv->hangcheck_disabled); /* Reset timer case chip hangs without another request being added */ mod_timer(&dev_priv->hangcheck_timer, jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); -- 1.7.5.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx