drm/i915: Protect gen7 irq_seqno_barrier with uncore lock
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 27 Apr 2016 08:02:01 +0000 (09:02 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Apr 2016 08:11:44 +0000 (09:11 +0100)
Faced with sporadic machine hangs on gen7, that mimic the issue of
concurrent writes to the same cacheline and seem to start with
commit 9b9ed3093613 (drm/i915: Remove forcewake dance from seqno/irq
barrier on legacy gen6+), let us restore the spinlock around the mmio
read.

Fixes: 9b9ed3093613 (drm/i915: Remove forcewake dance from seqno/irq...)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1461744121-27051-1-git-send-email-chris@chris-wilson.co.uk
Tested-by: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
drivers/gpu/drm/i915/intel_ringbuffer.c

index 66f69cdd1d36454aa9e00965b03a2148c7149f54..d6756ce6a586d8d3262c9d4d76c9c3639ff4eff2 100644 (file)
@@ -1577,6 +1577,8 @@ pc_render_add_request(struct drm_i915_gem_request *req)
 static void
 gen6_seqno_barrier(struct intel_engine_cs *engine)
 {
+       struct drm_i915_private *dev_priv = engine->dev->dev_private;
+
        /* Workaround to force correct ordering between irq and seqno writes on
         * ivb (and maybe also on snb) by reading from a CS register (like
         * ACTHD) before reading the status page.
@@ -1588,9 +1590,13 @@ gen6_seqno_barrier(struct intel_engine_cs *engine)
         * the write time to land, but that would incur a delay after every
         * batch i.e. much more frequent than a delay when waiting for the
         * interrupt (with the same net latency).
+        *
+        * Also note that to prevent whole machine hangs on gen7, we have to
+        * take the spinlock to guard against concurrent cacheline access.
         */
-       struct drm_i915_private *dev_priv = engine->dev->dev_private;
+       spin_lock_irq(&dev_priv->uncore.lock);
        POSTING_READ_FW(RING_ACTHD(engine->mmio_base));
+       spin_unlock_irq(&dev_priv->uncore.lock);
 }
 
 static u32