summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-19 10:54:35 +1000
committerDave Airlie <airlied@redhat.com>2014-06-19 10:54:35 +1000
commit884d6147ba19640a40fb45efe64360cdf92cac27 (patch)
treecf09a5ff5fb13474aba4eef7a68e56f46ca19381 /drivers/gpu/drm/i915/i915_irq.c
parentfb54918af7e7a607af8b70ba052a35ff8acb8620 (diff)
parent223a6f2b975ab35d93270ea1d4fb6e0ac6b27fe6 (diff)
downloadop-kernel-dev-884d6147ba19640a40fb45efe64360cdf92cac27.zip
op-kernel-dev-884d6147ba19640a40fb45efe64360cdf92cac27.tar.gz
Merge tag 'drm-intel-fixes-2014-06-17' of git://anongit.freedesktop.org/drm-intel into drm-next
First round of fixes for 3.16-rc, mostly cc: stable, and the vt/vgacon fixes from Daniel [1] to avoid hangs and unclaimed register errors on module load/reload. * tag 'drm-intel-fixes-2014-06-17' of git://anongit.freedesktop.org/drm-intel: drm/i915/bdw: remove erroneous chv specific workarounds from bdw code drm/i915: fix possible refcount leak when resetting forcewake drm/i915: Reorder semaphore deadlock check drm/i95: Initialize active ring->pid to -1 drm/i915: set backlight duty cycle after backlight enable for gen4 drm/i915: Avoid div-by-zero when pixel_multiplier is zero drm/i915: Disable FBC by default also on Haswell and later drm/i915: Kick out vga console drm/i915: Fixup global gtt cleanup vt: Don't ignore unbind errors in vt_unbind vt: Fix up unregistration of vt drivers vt: Fix replacement console check when unbinding
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 6f8017a..267f069 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2847,10 +2847,14 @@ static int semaphore_passed(struct intel_engine_cs *ring)
struct intel_engine_cs *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 */
@@ -2858,7 +2862,13 @@ static int semaphore_passed(struct intel_engine_cs *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)
@@ -2867,7 +2877,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
int i;
for_each_ring(ring, dev_priv, i)
- ring->hangcheck.deadlock = false;
+ ring->hangcheck.deadlock = 0;
}
static enum intel_ring_hangcheck_action
OpenPOWER on IntegriCloud