From patchwork Mon Nov 12 10:27:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 1727401 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 90EEFDFE80 for ; Mon, 12 Nov 2012 10:28:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3D4B89EFA6 for ; Mon, 12 Nov 2012 02:28:11 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from relay.fireflyinternet.com (relay1.fireflyinternet.com [217.160.24.105]) by gabe.freedesktop.org (Postfix) with ESMTP id 345E09E76C for ; Mon, 12 Nov 2012 02:27:59 -0800 (PST) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=109.228.6.235; Received: from fireflyinternet.com (unverified [109.228.6.235]) by relay.fireflyinternet.com (FireflyRelay1) with ESMTP id 87728-2000100 for ; Mon, 12 Nov 2012 10:27:49 +0000 X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.73.22; Received: from arrandale.alporthouse.com (unverified [78.156.73.22]) by fireflyinternet.com (Firefly Internet SMTP) with ESMTP id 125233758-1500050 for multiple; Mon, 12 Nov 2012 10:27:55 +0000 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Mon, 12 Nov 2012 10:27:45 +0000 Message-Id: <1352716065-17647-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.10.4 X-Originating-IP: 78.156.73.22 Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH] drm/i915: Serialize the reset worker and any waiters X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 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 Since the advent of trying to perform lockless-waits, commit 3236f57a0162391f84b93f39fc1882c49a8998c7 Author: Chris Wilson Date: Fri Aug 24 09:35:09 2012 +0100 drm/i915: Use a non-blocking wait for set-to-domain ioctl we exposed ourselves to a race between the reset-worker and those waiters. Previously the reset would have been serialized by the acquisition of the struct_mutex, but now we need to perform an explicit serialisation between the two. Signed-off-by: Chris Wilson Cc: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 ++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 2 ++ drivers/gpu/drm/i915/i915_irq.c | 2 ++ drivers/gpu/drm/i915/intel_display.c | 4 ++++ 5 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a35217d..50f5535 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1626,6 +1626,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) spin_lock_init(&dev_priv->rps.lock); spin_lock_init(&dev_priv->dpio_lock); + init_rwsem(&dev_priv->reset_lock); + mutex_init(&dev_priv->rps.hw_lock); if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cf407b1..fc5c152 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -42,6 +42,7 @@ #include #include #include +#include /* General customization: */ @@ -736,6 +737,7 @@ typedef struct drm_i915_private { unsigned int fsb_freq, mem_freq, is_ddr3; + struct rw_semaphore reset_lock; spinlock_t error_lock; /* Protected by dev->error_lock. */ struct drm_i915_error_state *first_error; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 30501d3..4ef5ba6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1140,6 +1140,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, /* Record current time in case interrupted by signal, or wedged * */ getrawmonotonic(&before); + down_read(&dev_priv->reset_lock); #define EXIT_COND \ (i915_seqno_passed(ring->get_seqno(ring, false), seqno) || \ @@ -1161,6 +1162,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, end = ret; } while (end == 0 && wait_forever); + up_read(&dev_priv->reset_lock); getrawmonotonic(&now); ring->irq_put(ring); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bfb6c51..54f2d92 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -875,6 +875,7 @@ static void i915_error_work_func(struct work_struct *work) kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); + down_write(&dev_priv->reset_lock); if (atomic_read(&dev_priv->mm.wedged)) { DRM_DEBUG_DRIVER("resetting chip\n"); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); @@ -884,6 +885,7 @@ static void i915_error_work_func(struct work_struct *work) } complete_all(&dev_priv->error_completion); } + up_write(&dev_priv->reset_lock); } /* NB: please notice the memset */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8a9df7d..816ea41 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2313,9 +2313,11 @@ intel_finish_fb(struct drm_framebuffer *old_fb) bool was_interruptible = dev_priv->mm.interruptible; int ret; + down_read(&dev_priv->reset_lock); wait_event(dev_priv->pending_flip_queue, atomic_read(&dev_priv->mm.wedged) || atomic_read(&obj->pending_flip) == 0); + up_read(&dev_priv->reset_lock); /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the @@ -3075,8 +3077,10 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) if (crtc->fb == NULL) return; + down_read(&dev_priv->reset_lock); wait_event(dev_priv->pending_flip_queue, !intel_crtc_has_pending_flip(crtc)); + up_read(&dev_priv->reset_lock); mutex_lock(&dev->struct_mutex); intel_finish_fb(crtc->fb);