drm/i915: Wake-up wait_request() from elapsed hang-check (v2)

If our watchdog fires and we see that the GPU is idle, but that we
are still waiting on an interrupt, forcibly wake-up the waiter.

i915_do_wait_request() should not be racy, yet there are persistent
reports that 945GM hangs whilst the GPU is idle. This implies that the
hardware is not quite as coherent as the documentation claims - a write
followed by a flush is supposed to be coherent in main memory before the
flush is retired and the irq is emitted. This seems to be a sensible and
elegant guard to force the wait to timeout.

v2: Daniel Vetter pointed out that a warning would be useful to explain
why the machine appeared to stall.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>

authored by

Chris Wilson and committed by
Eric Anholt
e78d73b1 6eeefaf3

+10
+10
drivers/gpu/drm/i915/i915_irq.c
··· 1304 1304 &dev_priv->render_ring), 1305 1305 i915_get_tail_request(dev)->seqno)) { 1306 1306 dev_priv->hangcheck_count = 0; 1307 + 1308 + /* Issue a wake-up to catch stuck h/w. */ 1309 + if (dev_priv->render_ring.waiting_gem_seqno | 1310 + dev_priv->bsd_ring.waiting_gem_seqno) { 1311 + DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); 1312 + if (dev_priv->render_ring.waiting_gem_seqno) 1313 + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); 1314 + if (dev_priv->bsd_ring.waiting_gem_seqno) 1315 + DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); 1316 + } 1307 1317 return; 1308 1318 } 1309 1319