From patchwork Mon Sep 14 21:48:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gamari X-Patchwork-Id: 47480 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n8ELn9xP032326 for ; Mon, 14 Sep 2009 21:49:10 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AEB249F4FC; Mon, 14 Sep 2009 14:49:09 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-qy0-f202.google.com (mail-qy0-f202.google.com [209.85.221.202]) by gabe.freedesktop.org (Postfix) with ESMTP id D629D9F4E1 for ; Mon, 14 Sep 2009 14:49:05 -0700 (PDT) Received: by qyk40 with SMTP id 40so2786144qyk.8 for ; Mon, 14 Sep 2009 14:49:05 -0700 (PDT) Received: by 10.224.13.66 with SMTP id b2mr5693776qaa.370.1252964945044; Mon, 14 Sep 2009 14:49:05 -0700 (PDT) Received: from localhost.localdomain ([128.119.194.104]) by mx.google.com with ESMTPS id 20sm2140955qyk.9.2009.09.14.14.49.03 (version=SSLv3 cipher=RC4-MD5); Mon, 14 Sep 2009 14:49:04 -0700 (PDT) From: Ben Gamari To: Jesse Barnes , Chris Wilson Date: Mon, 14 Sep 2009 17:48:47 -0400 Message-Id: <1252964927-28043-8-git-send-email-bgamari.foss@gmail.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1252964927-28043-7-git-send-email-bgamari.foss@gmail.com> References: <1252964927-28043-1-git-send-email-bgamari.foss@gmail.com> <1252964927-28043-2-git-send-email-bgamari.foss@gmail.com> <1252964927-28043-3-git-send-email-bgamari.foss@gmail.com> <1252964927-28043-4-git-send-email-bgamari.foss@gmail.com> <1252964927-28043-5-git-send-email-bgamari.foss@gmail.com> <1252964927-28043-6-git-send-email-bgamari.foss@gmail.com> <1252964927-28043-7-git-send-email-bgamari.foss@gmail.com> Cc: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH 7/8] Make dev_priv->mm.wedged an atomic_t X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 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@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org There is a very real possibility that multiple CPUs will notice that the GPU is wedged. This introduces all sorts of potential race conditions. Make the wedged flag atomic to mitigate this risk. Signed-off-by: Ben Gamari --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 18 +++++++++--------- drivers/gpu/drm/i915/i915_irq.c | 15 ++++++++------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 42142f2..bcc1be2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -450,7 +450,7 @@ typedef struct drm_i915_private { * It prevents command submission from occuring and makes * every pending request fail */ - int wedged; + atomic_t wedged; /** Bit 6 swizzling required for X tiling */ uint32_t bit_6_swizzle_x; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 579b3b0..f0f6f66 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1712,7 +1712,7 @@ i915_gem_retire_requests(struct drm_device *dev) retiring_seqno = request->seqno; if (i915_seqno_passed(seqno, retiring_seqno) || - dev_priv->mm.wedged) { + atomic_read(&dev_priv->mm.wedged)) { i915_gem_retire_request(dev, request); list_del(&request->list); @@ -1754,7 +1754,7 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) BUG_ON(seqno == 0); - if (dev_priv->mm.wedged) + if (atomic_read(&dev_priv->mm.wedged)) return -EIO; if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { @@ -1774,11 +1774,11 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) ret = wait_event_interruptible(dev_priv->irq_queue, i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || - dev_priv->mm.wedged); + atomic_read(&dev_priv->mm.wedged)); i915_user_irq_put(dev); dev_priv->mm.waiting_gem_seqno = 0; } - if (dev_priv->mm.wedged) + if (atomic_read(&dev_priv->mm.wedged)) ret = -EIO; if (ret && ret != -ERESTARTSYS) @@ -3359,7 +3359,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, i915_verify_inactive(dev, __FILE__, __LINE__); - if (dev_priv->mm.wedged) { + if (atomic_read(&dev_priv->mm.wedged)) { DRM_ERROR("Execbuf while wedged\n"); mutex_unlock(&dev->struct_mutex); ret = -EIO; @@ -3929,7 +3929,7 @@ i915_gem_idle(struct drm_device *dev) if (last_seqno == cur_seqno) { if (stuck++ > 100) { DRM_ERROR("hardware wedged\n"); - dev_priv->mm.wedged = 1; + atomic_set(&dev_priv->mm.wedged, 1); DRM_WAKEUP(&dev_priv->irq_queue); break; } @@ -3942,7 +3942,7 @@ i915_gem_idle(struct drm_device *dev) i915_gem_retire_requests(dev); spin_lock(&dev_priv->mm.active_list_lock); - if (!dev_priv->mm.wedged) { + if (!atomic_read(&dev_priv->mm.wedged)) { /* Active and flushing should now be empty as we've * waited for a sequence higher than any pending execbuffer */ @@ -4204,9 +4204,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; - if (dev_priv->mm.wedged) { + if (atomic_read(&dev_priv->mm.wedged)) { DRM_ERROR("Reenabling wedged hardware, good luck\n"); - dev_priv->mm.wedged = 0; + atomic_set(&dev_priv->mm.wedged, 0); } mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8f52766..13e664d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -309,12 +309,12 @@ static void i915_error_work_func(struct work_struct *work) DRM_DEBUG("generating error event\n"); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); - if (dev_priv->mm.wedged) { + if (atomic_read(&dev_priv->mm.wedged)) { if (IS_I965G(dev)) { DRM_DEBUG("resetting chip\n"); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); if (!i965_reset(dev, GDRST_RENDER)) { - dev_priv->mm.wedged = 0; + atomic_set(&dev_priv->mm.wedged, 0); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event); } } else { @@ -385,7 +385,7 @@ out: * so userspace knows something bad happened (should trigger collection * of a ring dump etc.). */ -static void i915_handle_error(struct drm_device *dev) +static void i915_handle_error(struct drm_device *dev, bool wedged) { struct drm_i915_private *dev_priv = dev->dev_private; u32 eir = I915_READ(EIR); @@ -495,7 +495,9 @@ static void i915_handle_error(struct drm_device *dev) I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); } - if (dev_priv->mm.wedged) { + if (wedged) { + atomic_set(&dev_priv->mm.wedged, 1); + /* * Wakeup waiting processes so they don't hang */ @@ -548,7 +550,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) pipeb_stats = I915_READ(PIPEBSTAT); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) - i915_handle_error(dev); + i915_handle_error(dev, false); /* * Clear the PIPE(A|B)STAT regs before the IIR @@ -934,8 +936,7 @@ void i915_hangcheck_elapsed(unsigned long data) if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); - dev_priv->mm.wedged = true; /* Hopefully this is atomic */ - i915_handle_error(dev); + i915_handle_error(dev, true); return; }