From ff320d6e72ff3600184a1c01ea75b689b4b8a16d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Oct 2017 22:32:35 +0100 Subject: [PATCH] drm/i915: Synchronize irq before parking each engine When we park the engine (upon idling), we kill the irq tasklet. However, to be sure that it is not restarted by a spurious interrupt after doing so, flush the interrupt handler before parking. As we only park the engines when we believe the system is idle, there should not be any interrupts to distrub us; so flushing the final in-flight interrupt should be sufficient. (However, we are still dependent on the HW behaving in an orderly and timely fashion, which we shall endeavour to improve upon later.) Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Mika Kuoppala Cc: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20171023213237.26536-2-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bb0e85043e01..bafe1cdd57d8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3328,6 +3328,19 @@ i915_gem_idle_work_handler(struct work_struct *work) goto out_unlock; /* + * Be paranoid and flush a concurrent interrupt to make sure + * we don't reactivate any irq tasklets after parking. + * + * FIXME: Note that even though we have waited for execlists to be idle, + * there may still be an in-flight interrupt even though the CSB + * is now empty. synchronize_irq() makes sure that a residual interrupt + * is completed before we continue, but it doesn't prevent the HW from + * raising a spurious interrupt later. To complete the shield we should + * coordinate disabling the CS irq with flushing the interrupts. + */ + synchronize_irq(dev_priv->drm.irq); + + /* * We are committed now to parking the engines, make sure there * will be no more interrupts arriving later. */ -- 2.11.0