From f0cd9176976b40b85a72b1048f0e60b6a4263077 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 11 Apr 2014 13:42:05 +0100 Subject: [PATCH] drm/i915: Reorder semaphore deadlock check 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 kick the second ring and so can treat the first ring as a valid WAIT and not as HUNG. References: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f21ebfc..3e0c559 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2616,7 +2616,7 @@ static int semaphore_passed(struct intel_ring_buffer *ring) ring->hangcheck.deadlock = true; signaller = semaphore_waits_for(ring, &seqno); - if (signaller == NULL || signaller->hangcheck.deadlock) + if (signaller == NULL) return -1; /* cursory check for an unkickable deadlock */ @@ -2624,7 +2624,13 @@ static int semaphore_passed(struct intel_ring_buffer *ring) 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) -- 1.9.0