I couldn't reproduce this one, but... Interrupt mask state is lost if three interrupts occur before the workqueue has run.
Should be straight forward to reproduce even without SMP. I'm pretty sure Dan Vetter was trying to explain this to me, and I couldn't get it. My solution I think is different than his though. Here is a sample failure: <pm irq 1<<0 occurs> local iir = 1 spin lock mask_pm_irq(1 << 0); dev_priv->iir = 1; spin_unlock clear_pm_irq(1 << 0); <pm irq 1 << 1 occurs> local iir = 2 spin lock mask_pm_irq(1 << 1); // here is the bug dev_priv->iir = 3; clear_pm_irq(1 << 1); <pm irq 1 << 0 occurs again> local iir = 1 spin lock WARN!!! Cc: Chris Wilson <[email protected]> Cc: Daniel Vetter <[email protected]> Signed-off-by: Ben Widawsky <[email protected]> --- drivers/gpu/drm/i915/i915_irq.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9cbb0cd..55518e3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -649,8 +649,8 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) unsigned long flags; spin_lock_irqsave(&dev_priv->rps_lock, flags); WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); - I915_WRITE(GEN6_PMIMR, pm_iir); dev_priv->pm_iir |= pm_iir; + I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); spin_unlock_irqrestore(&dev_priv->rps_lock, flags); queue_work(dev_priv->wq, &dev_priv->rps_work); } -- 1.7.6.1 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
