This is a note to let you know that I've just added the patch titled drm/i915: Reorder semaphore deadlock check to the 3.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-i915-reorder-semaphore-deadlock-check.patch and it can be found in the queue-3.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 4be173813e57c7298103a83155c2391b5b167b4c Mon Sep 17 00:00:00 2001 From: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Date: Fri, 6 Jun 2014 10:22:29 +0100 Subject: drm/i915: Reorder semaphore deadlock check From: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> commit 4be173813e57c7298103a83155c2391b5b167b4c upstream. If a semaphore is waiting on another ring, which in turn happens to be waiting on the first ring, but that second semaphore has been signalled, we will be able to kick the second ring and so can treat the first ring as a valid WAIT and not as HUNG. v2: Be paranoid and cap the potential recursion depth whilst visiting the semaphore signallers. (Mika) References: https://bugs.freedesktop.org/show_bug.cgi?id=54226 References: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> Reviewed-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_irq.c | 18 ++++++++++++++---- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2561,10 +2561,14 @@ static int semaphore_passed(struct intel struct intel_ring_buffer *signaller; u32 seqno, ctl; - ring->hangcheck.deadlock = true; + ring->hangcheck.deadlock++; signaller = semaphore_waits_for(ring, &seqno); - if (signaller == NULL || signaller->hangcheck.deadlock) + if (signaller == NULL) + return -1; + + /* Prevent pathological recursion due to driver bugs */ + if (signaller->hangcheck.deadlock >= I915_NUM_RINGS) return -1; /* cursory check for an unkickable deadlock */ @@ -2572,7 +2576,13 @@ static int semaphore_passed(struct intel if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0) return -1; - return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno); + if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno)) + return 1; + + if (signaller->hangcheck.deadlock) + return -1; + + return 0; } static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) @@ -2581,7 +2591,7 @@ static void semaphore_clear_deadlocks(st int i; for_each_ring(ring, dev_priv, i) - ring->hangcheck.deadlock = false; + ring->hangcheck.deadlock = 0; } static enum intel_ring_hangcheck_action --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -51,7 +51,7 @@ struct intel_ring_hangcheck { u32 seqno; int score; enum intel_ring_hangcheck_action action; - bool deadlock; + int deadlock; }; struct intel_ring_buffer { Patches currently in stable-queue which might be from chris@xxxxxxxxxxxxxxxxxx are queue-3.15/drm-i915-hold-the-table-lock-whilst-walking-the-file-s-idr-and-counting-the-objects-in-debugfs.patch queue-3.15/drm-i915-disable-fbc-by-default-also-on-haswell-and-later.patch queue-3.15/drm-i915-reorder-semaphore-deadlock-check.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html