From 901b12c0a4f9a5c8dbdf95a16d80cc04ce222a02 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 3 Feb 2015 12:03:57 +0200 Subject: [PATCH] drm/i915: Use ring head/tail to check ring idle in hangcheck Request will be emitted to ring before it is added to request_list. There is then a window where the ring_idle might return true even if there is work in the ring. In order to prevent such inconsistencies in our own state keeping, check if ring is idle by actually inspecting the head/tail. References: https://bugs.freedesktop.org/show_bug.cgi?id=88651 Signed-off-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_irq.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 53c5f9e..556a2f9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2770,18 +2770,17 @@ static void gen8_disable_vblank(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } -static struct drm_i915_gem_request * -ring_last_request(struct intel_engine_cs *ring) -{ - return list_entry(ring->request_list.prev, - struct drm_i915_gem_request, list); -} - static bool ring_idle(struct intel_engine_cs *ring) { - return (list_empty(&ring->request_list) || - i915_gem_request_completed(ring_last_request(ring), false)); + struct drm_i915_private *dev_priv = ring->dev->dev_private; + + /* Forced tail update */ + __intel_ring_advance(ring); + + ring->buffer->head = I915_READ_HEAD(ring); + + return (ring->buffer->head & HEAD_ADDR) == ring->buffer->tail; } static bool -- 1.9.1