From: Imre Deak Date: Mon, 23 Mar 2015 17:11:34 +0000 (+0200) Subject: drm/i915: fix race when clearing RPS IIR bits X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=58072ccbb81c6f2d67c5b4cc7597707c4fb86a5e;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git drm/i915: fix race when clearing RPS IIR bits When disabling RPS interrupts there is a race where we disable RPS inerrupts while the interrupt handler is running and the handler has already latched the pending RPS interrupt from the master IIR register. Afterwards the disabling path clears the PM IIR bits, making the state of pending interrupts inconsistent from the interrupt handler's point of view. This triggers the following warning: "The master control interrupt lied (PM)!". To fix this make sure that any running interrupt handler (which may have already latched the master IIR) finishes before clearing the IIR bits. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87347 Signed-off-by: Imre Deak Signed-off-by: Daniel Vetter --- diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6d8340d5a111..7afbde4c13e9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -330,6 +330,13 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & ~dev_priv->pm_rps_events); + + spin_unlock_irq(&dev_priv->irq_lock); + + synchronize_irq(dev->irq); + + spin_lock_irq(&dev_priv->irq_lock); + I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);