From patchwork Wed Jun 22 23:07:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 907612 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5MN8Xa9001749 for ; Wed, 22 Jun 2011 23:08:53 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6FDC99ECDD for ; Wed, 22 Jun 2011 16:08:33 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from cloud01.chad-versace.us (184-106-247-128.static.cloud-ips.com [184.106.247.128]) by gabe.freedesktop.org (Postfix) with ESMTP id C77899E81E for ; Wed, 22 Jun 2011 16:07:46 -0700 (PDT) Received: from localhost.localdomain (jfdmzpr03-ext.jf.intel.com [134.134.139.72]) by cloud01.chad-versace.us (Postfix) with ESMTPSA id DC6EA1D4264; Wed, 22 Jun 2011 23:09:49 +0000 (UTC) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Wed, 22 Jun 2011 16:07:39 -0700 Message-Id: <1308784059-5863-2-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.7.5.2 In-Reply-To: <1308784059-5863-1-git-send-email-ben@bwidawsk.net> References: <1308784059-5863-1-git-send-email-ben@bwidawsk.net> Subject: [Intel-gfx] [PATCH 2/2] drm/i915: debugger debugfs entry X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 22 Jun 2011 23:08:53 +0000 (UTC) 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));