* [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states
@ 2015-02-20 19:09 Imre Deak
2015-02-20 19:40 ` Chris Wilson
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Imre Deak @ 2015-02-20 19:09 UTC (permalink / raw)
To: intel-gfx; +Cc: Jani Nikula, Klaus Ethgen
Atm, it's possible that the interrupt handler is called when the device
is in D3 or some other low-power state. It can be due to another device
that is still in D0 state and shares the interrupt line with i915, or on
some platforms there could be spurious interrupts even without sharing
the interrupt line. The latter case was reported by Klaus Ethgen using a
Lenovo x61p machine (gen 4). He noticed this issue via a system
suspend/resume hang and bisected it to the following commit:
commit e11aa362308f5de467ce355a2a2471321b15a35c
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Wed Jun 18 09:52:55 2014 -0700
drm/i915: use runtime irq suspend/resume in freeze/thaw
This is a problem, since in low-power states IIR will always read
0xffffffff resulting in an endless IRQ servicing loop.
Fix this by handling interrupts only when the driver explicitly enables
them and so it's guaranteed that the interrupt registers return a valid
value.
Note that this issue existed even before the above commit, since during
runtime suspend/resume we never unregistered the handler.
Reference: https://lkml.org/lkml/2015/2/11/205
Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 43 +++++++++++++++++++++++++++++++++++++----
1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9073119..0dc0382 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
while (true) {
/* Find, clear, then process each source of interrupt */
@@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
for (;;) {
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
iir = I915_READ(VLV_IIR);
@@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
/* We get interrupts on unclaimed registers, so check for this before we
* do any I915_{READ,WRITE}. */
intel_uncore_check_errors(dev);
@@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
if (IS_GEN9(dev))
aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ16(IIR);
if (iir == 0)
return IRQ_NONE;
@@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
do {
bool irq_received = (iir & ~flip_mask) != 0;
@@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
for (;;) {
@@ -4469,6 +4490,20 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
spin_unlock_irq(&dev_priv->irq_lock);
}
+static void intel_irq_set_state(struct drm_i915_private *dev_priv,
+ bool enabled)
+{
+ dev_priv->pm.irqs_enabled = enabled;
+ /*
+ * Before we unmask the interrupt or synchronize against it, make sure
+ * that a corresponding interrupt handler running on another CPU sees
+ * the updated irqs_enabled value.
+ */
+ smp_mb();
+ if (!enabled)
+ synchronize_irq(dev_priv->dev->irq);
+}
+
/**
* intel_irq_install - enables the hardware interrupt
* @dev_priv: i915 device instance
@@ -4487,7 +4522,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv)
* interrupts as enabled _before_ actually enabling them to avoid
* special cases in our ordering checks.
*/
- dev_priv->pm.irqs_enabled = true;
+ intel_irq_set_state(dev_priv, true);
return drm_irq_install(dev_priv->dev, dev_priv->dev->pdev->irq);
}
@@ -4503,7 +4538,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
{
drm_irq_uninstall(dev_priv->dev);
intel_hpd_cancel_work(dev_priv);
- dev_priv->pm.irqs_enabled = false;
+ intel_irq_set_state(dev_priv, false);
}
/**
@@ -4516,7 +4551,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
{
dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
- dev_priv->pm.irqs_enabled = false;
+ intel_irq_set_state(dev_priv, false);
}
/**
@@ -4528,7 +4563,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
*/
void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv)
{
- dev_priv->pm.irqs_enabled = true;
+ intel_irq_set_state(dev_priv, true);
dev_priv->dev->driver->irq_preinstall(dev_priv->dev);
dev_priv->dev->driver->irq_postinstall(dev_priv->dev);
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-20 19:09 [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states Imre Deak
@ 2015-02-20 19:40 ` Chris Wilson
2015-02-20 19:53 ` Imre Deak
2015-02-20 22:26 ` shuang.he
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
2 siblings, 1 reply; 15+ messages in thread
From: Chris Wilson @ 2015-02-20 19:40 UTC (permalink / raw)
To: Imre Deak; +Cc: Jani Nikula, Klaus Ethgen, intel-gfx
On Fri, Feb 20, 2015 at 09:09:02PM +0200, Imre Deak wrote:
> +static void intel_irq_set_state(struct drm_i915_private *dev_priv,
> + bool enabled)
> +{
> + dev_priv->pm.irqs_enabled = enabled;
> + /*
> + * Before we unmask the interrupt or synchronize against it, make sure
> + * that a corresponding interrupt handler running on another CPU sees
> + * the updated irqs_enabled value.
> + */
> + smp_mb();
I would like a comment here to say something like: before powering down
the hardware make sure that we have no further access via pending
interrupt handlers. At the moment, I read the block comment above and
thought you were trying to imply something about the serialisation from
synchronize_irq() - but the only reason I can see you want sync_irq here
is to be sure that once the irq is disabled it is not going to run again.
> + if (!enabled)
> + synchronize_irq(dev_priv->dev->irq);
> +}
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-20 19:40 ` Chris Wilson
@ 2015-02-20 19:53 ` Imre Deak
0 siblings, 0 replies; 15+ messages in thread
From: Imre Deak @ 2015-02-20 19:53 UTC (permalink / raw)
To: Chris Wilson; +Cc: Jani Nikula, Klaus Ethgen, intel-gfx
On Fri, 2015-02-20 at 19:40 +0000, Chris Wilson wrote:
> On Fri, Feb 20, 2015 at 09:09:02PM +0200, Imre Deak wrote:
> > +static void intel_irq_set_state(struct drm_i915_private *dev_priv,
> > + bool enabled)
> > +{
> > + dev_priv->pm.irqs_enabled = enabled;
> > + /*
> > + * Before we unmask the interrupt or synchronize against it, make sure
> > + * that a corresponding interrupt handler running on another CPU sees
> > + * the updated irqs_enabled value.
> > + */
> > + smp_mb();
>
> I would like a comment here to say something like: before powering down
> the hardware make sure that we have no further access via pending
> interrupt handlers. At the moment, I read the block comment above and
> thought you were trying to imply something about the serialisation from
> synchronize_irq() - but the only reason I can see you want sync_irq here
> is to be sure that once the irq is disabled it is not going to run again.
Right. With sync_irq I want to wait for any running handler on another
CPU to finish. Subsequent ones due to any shared/spurious interrupts
will also not run since the barrier guarantees that they see already the
updated value and do an early return. Will add a comment about this.
>
> > + if (!enabled)
> > + synchronize_irq(dev_priv->dev->irq);
> > +}
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-20 19:09 [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states Imre Deak
2015-02-20 19:40 ` Chris Wilson
@ 2015-02-20 22:26 ` shuang.he
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
2 siblings, 0 replies; 15+ messages in thread
From: shuang.he @ 2015-02-20 22:26 UTC (permalink / raw)
To: shuang.he, ethan.gao, intel-gfx, imre.deak
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5801
-------------------------------------Summary-------------------------------------
Platform Delta drm-intel-nightly Series Applied
PNV 277/277 277/277
ILK -1 313/313 312/313
SNB 309/309 309/309
IVB 382/382 382/382
BYT 296/296 296/296
HSW 425/425 425/425
BDW -1 318/318 317/318
-------------------------------------Detailed-------------------------------------
Platform Test drm-intel-nightly Series Applied
*ILK igt_gem_unfence_active_buffers PASS(2) DMESG_WARN(1)PASS(1)
*BDW igt_gem_gtt_hog PASS(18) DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-20 19:09 [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states Imre Deak
2015-02-20 19:40 ` Chris Wilson
2015-02-20 22:26 ` shuang.he
@ 2015-02-23 9:58 ` Imre Deak
2015-02-23 11:57 ` Chris Wilson
` (3 more replies)
2 siblings, 4 replies; 15+ messages in thread
From: Imre Deak @ 2015-02-23 9:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Jani Nikula, Klaus Ethgen
Atm, it's possible that the interrupt handler is called when the device
is in D3 or some other low-power state. It can be due to another device
that is still in D0 state and shares the interrupt line with i915, or on
some platforms there could be spurious interrupts even without sharing
the interrupt line. The latter case was reported by Klaus Ethgen using a
Lenovo x61p machine (gen 4). He noticed this issue via a system
suspend/resume hang and bisected it to the following commit:
commit e11aa362308f5de467ce355a2a2471321b15a35c
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Wed Jun 18 09:52:55 2014 -0700
drm/i915: use runtime irq suspend/resume in freeze/thaw
This is a problem, since in low-power states IIR will always read
0xffffffff resulting in an endless IRQ servicing loop.
Fix this by handling interrupts only when the driver explicitly enables
them and so it's guaranteed that the interrupt registers return a valid
value.
Note that this issue existed even before the above commit, since during
runtime suspend/resume we never unregistered the handler.
v2:
- clarify the purpose of smp_mb() vs. synchronize_irq() in the
code comment(Chris)
Reference: https://lkml.org/lkml/2015/2/11/205
Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 51 +++++++++++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9073119..b17c953 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
while (true) {
/* Find, clear, then process each source of interrupt */
@@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
for (;;) {
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
iir = I915_READ(VLV_IIR);
@@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
/* We get interrupts on unclaimed registers, so check for this before we
* do any I915_{READ,WRITE}. */
intel_uncore_check_errors(dev);
@@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
if (IS_GEN9(dev))
aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ16(IIR);
if (iir == 0)
return IRQ_NONE;
@@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
do {
bool irq_received = (iir & ~flip_mask) != 0;
@@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
for (;;) {
@@ -4469,6 +4490,28 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
spin_unlock_irq(&dev_priv->irq_lock);
}
+static void intel_irq_set_state(struct drm_i915_private *dev_priv,
+ bool enabled)
+{
+ dev_priv->pm.irqs_enabled = enabled;
+ /*
+ * Before we unmask or after we masked the interrupt make sure that
+ * any interrupt handler running on another CPU sees the updated
+ * irqs_enabled value. Note that when masking the interrupt the
+ * subsequent synchronize_irq doesn't guarantee this, because the
+ * interrupt handler can be called to service shared/spurious
+ * interrupts even after synchronize_irq.
+ */
+ smp_mb();
+ /*
+ * Make sure that any interrupt handler pending on another CPU
+ * finishes. Otherwise such a handler could access registers after we
+ * powered down the hardware.
+ */
+ if (!enabled)
+ synchronize_irq(dev_priv->dev->irq);
+}
+
/**
* intel_irq_install - enables the hardware interrupt
* @dev_priv: i915 device instance
@@ -4487,7 +4530,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv)
* interrupts as enabled _before_ actually enabling them to avoid
* special cases in our ordering checks.
*/
- dev_priv->pm.irqs_enabled = true;
+ intel_irq_set_state(dev_priv, true);
return drm_irq_install(dev_priv->dev, dev_priv->dev->pdev->irq);
}
@@ -4503,7 +4546,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
{
drm_irq_uninstall(dev_priv->dev);
intel_hpd_cancel_work(dev_priv);
- dev_priv->pm.irqs_enabled = false;
+ intel_irq_set_state(dev_priv, false);
}
/**
@@ -4516,7 +4559,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
{
dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
- dev_priv->pm.irqs_enabled = false;
+ intel_irq_set_state(dev_priv, false);
}
/**
@@ -4528,7 +4571,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
*/
void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv)
{
- dev_priv->pm.irqs_enabled = true;
+ intel_irq_set_state(dev_priv, true);
dev_priv->dev->driver->irq_preinstall(dev_priv->dev);
dev_priv->dev->driver->irq_postinstall(dev_priv->dev);
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
@ 2015-02-23 11:57 ` Chris Wilson
2015-02-23 14:26 ` shuang.he
` (2 subsequent siblings)
3 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2015-02-23 11:57 UTC (permalink / raw)
To: Imre Deak; +Cc: Jani Nikula, Klaus Ethgen, intel-gfx
On Mon, Feb 23, 2015 at 11:58:14AM +0200, Imre Deak wrote:
> Atm, it's possible that the interrupt handler is called when the device
> is in D3 or some other low-power state. It can be due to another device
> that is still in D0 state and shares the interrupt line with i915, or on
> some platforms there could be spurious interrupts even without sharing
> the interrupt line. The latter case was reported by Klaus Ethgen using a
> Lenovo x61p machine (gen 4). He noticed this issue via a system
> suspend/resume hang and bisected it to the following commit:
>
> commit e11aa362308f5de467ce355a2a2471321b15a35c
> Author: Jesse Barnes <jbarnes@virtuousgeek.org>
> Date: Wed Jun 18 09:52:55 2014 -0700
>
> drm/i915: use runtime irq suspend/resume in freeze/thaw
>
> This is a problem, since in low-power states IIR will always read
> 0xffffffff resulting in an endless IRQ servicing loop.
>
> Fix this by handling interrupts only when the driver explicitly enables
> them and so it's guaranteed that the interrupt registers return a valid
> value.
>
> Note that this issue existed even before the above commit, since during
> runtime suspend/resume we never unregistered the handler.
>
> v2:
> - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> code comment(Chris)
>
> Reference: https://lkml.org/lkml/2015/2/11/205
> Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
Thanks! That comment makes it very clear.
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
2015-02-23 11:57 ` Chris Wilson
@ 2015-02-23 14:26 ` shuang.he
2015-02-23 14:31 ` [PATCH v3] " Imre Deak
2015-02-24 9:14 ` [PATCH v4] " Imre Deak
3 siblings, 0 replies; 15+ messages in thread
From: shuang.he @ 2015-02-23 14:26 UTC (permalink / raw)
To: shuang.he, ethan.gao, intel-gfx, imre.deak
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5809
-------------------------------------Summary-------------------------------------
Platform Delta drm-intel-nightly Series Applied
PNV -1 281/281 280/281
ILK 308/308 308/308
SNB -2 326/326 324/326
IVB 380/380 380/380
BYT 294/294 294/294
HSW -3 421/421 418/421
BDW -1 316/316 315/316
-------------------------------------Detailed-------------------------------------
Platform Test drm-intel-nightly Series Applied
*PNV igt_gen3_render_mixed_blits PASS(3) CRASH(1)PASS(1)
*SNB igt_kms_plane_plane-position-hole-pipe-B-plane-2 DMESG_WARN(12)PASS(2) TIMEOUT(1)PASS(1)
*SNB igt_kms_rotation_crc_sprite-rotation DMESG_WARN(11)PASS(3) FAIL(1)PASS(1)
*HSW igt_gem_pwrite_pread_snooped-pwrite-blt-cpu_mmap-performance PASS(3) DMESG_WARN(1)PASS(1)
HSW igt_gem_storedw_loop_vebox DMESG_WARN(1)PASS(1) DMESG_WARN(1)PASS(1)
*HSW igt_kms_flip_plain-flip-fb-recreate-interruptible PASS(2) TIMEOUT(2)
*BDW igt_gem_gtt_hog PASS(2) DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
2015-02-23 11:57 ` Chris Wilson
2015-02-23 14:26 ` shuang.he
@ 2015-02-23 14:31 ` Imre Deak
2015-02-24 0:07 ` Daniel Vetter
2015-02-24 13:56 ` shuang.he
2015-02-24 9:14 ` [PATCH v4] " Imre Deak
3 siblings, 2 replies; 15+ messages in thread
From: Imre Deak @ 2015-02-23 14:31 UTC (permalink / raw)
To: intel-gfx; +Cc: Jani Nikula, Klaus Ethgen, Daniel Vetter
Atm, it's possible that the interrupt handler is called when the device
is in D3 or some other low-power state. It can be due to another device
that is still in D0 state and shares the interrupt line with i915, or on
some platforms there could be spurious interrupts even without sharing
the interrupt line. The latter case was reported by Klaus Ethgen using a
Lenovo x61p machine (gen 4). He noticed this issue via a system
suspend/resume hang and bisected it to the following commit:
commit e11aa362308f5de467ce355a2a2471321b15a35c
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Wed Jun 18 09:52:55 2014 -0700
drm/i915: use runtime irq suspend/resume in freeze/thaw
This is a problem, since in low-power states IIR will always read
0xffffffff resulting in an endless IRQ servicing loop.
Fix this by handling interrupts only when the driver explicitly enables
them and so it's guaranteed that the interrupt registers return a valid
value.
Note that this issue existed even before the above commit, since during
runtime suspend/resume we never unregistered the handler.
v2:
- clarify the purpose of smp_mb() vs. synchronize_irq() in the
code comment (Chris)
v3:
- no need for an explicit smp_mb(), we can assume that synchronize_irq()
and the mmio read/writes in the install hooks provide for this (Daniel)
- remove code comment as the remaining synchronize_irq() is self
explanatory (Daniel)
Reference: https://lkml.org/lkml/2015/2/11/205
Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9073119..612c9c0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
while (true) {
/* Find, clear, then process each source of interrupt */
@@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
for (;;) {
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
iir = I915_READ(VLV_IIR);
@@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
/* We get interrupts on unclaimed registers, so check for this before we
* do any I915_{READ,WRITE}. */
intel_uncore_check_errors(dev);
@@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
if (IS_GEN9(dev))
aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ16(IIR);
if (iir == 0)
return IRQ_NONE;
@@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
do {
bool irq_received = (iir & ~flip_mask) != 0;
@@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
for (;;) {
@@ -4504,6 +4525,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
drm_irq_uninstall(dev_priv->dev);
intel_hpd_cancel_work(dev_priv);
dev_priv->pm.irqs_enabled = false;
+ synchronize_irq(dev_priv->dev->irq);
}
/**
@@ -4517,6 +4539,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
{
dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
dev_priv->pm.irqs_enabled = false;
+ synchronize_irq(dev_priv->dev->irq);
}
/**
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v3] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-23 14:31 ` [PATCH v3] " Imre Deak
@ 2015-02-24 0:07 ` Daniel Vetter
2015-02-24 13:56 ` shuang.he
1 sibling, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2015-02-24 0:07 UTC (permalink / raw)
To: Imre Deak; +Cc: Jani Nikula, Klaus Ethgen, intel-gfx, Daniel Vetter
On Mon, Feb 23, 2015 at 04:31:49PM +0200, Imre Deak wrote:
> Atm, it's possible that the interrupt handler is called when the device
> is in D3 or some other low-power state. It can be due to another device
> that is still in D0 state and shares the interrupt line with i915, or on
> some platforms there could be spurious interrupts even without sharing
> the interrupt line. The latter case was reported by Klaus Ethgen using a
> Lenovo x61p machine (gen 4). He noticed this issue via a system
> suspend/resume hang and bisected it to the following commit:
>
> commit e11aa362308f5de467ce355a2a2471321b15a35c
> Author: Jesse Barnes <jbarnes@virtuousgeek.org>
> Date: Wed Jun 18 09:52:55 2014 -0700
>
> drm/i915: use runtime irq suspend/resume in freeze/thaw
>
> This is a problem, since in low-power states IIR will always read
> 0xffffffff resulting in an endless IRQ servicing loop.
>
> Fix this by handling interrupts only when the driver explicitly enables
> them and so it's guaranteed that the interrupt registers return a valid
> value.
>
> Note that this issue existed even before the above commit, since during
> runtime suspend/resume we never unregistered the handler.
>
> v2:
> - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> code comment (Chris)
>
> v3:
> - no need for an explicit smp_mb(), we can assume that synchronize_irq()
> and the mmio read/writes in the install hooks provide for this (Daniel)
> - remove code comment as the remaining synchronize_irq() is self
> explanatory (Daniel)
>
> Reference: https://lkml.org/lkml/2015/2/11/205
> Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_irq.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 9073119..612c9c0 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
> u32 iir, gt_iir, pm_iir;
> irqreturn_t ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> while (true) {
> /* Find, clear, then process each source of interrupt */
>
> @@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
> u32 master_ctl, iir;
> irqreturn_t ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> for (;;) {
> master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
> iir = I915_READ(VLV_IIR);
> @@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
> u32 de_iir, gt_iir, de_ier, sde_ier = 0;
> irqreturn_t ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> /* We get interrupts on unclaimed registers, so check for this before we
> * do any I915_{READ,WRITE}. */
> intel_uncore_check_errors(dev);
> @@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
> enum pipe pipe;
> u32 aux_mask = GEN8_AUX_CHANNEL_A;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> if (IS_GEN9(dev))
> aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
> GEN9_AUX_CHANNEL_D;
> @@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
> I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
> I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> iir = I915_READ16(IIR);
> if (iir == 0)
> return IRQ_NONE;
> @@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
> I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
> int pipe, ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> iir = I915_READ(IIR);
> do {
> bool irq_received = (iir & ~flip_mask) != 0;
> @@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
> I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
> I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> iir = I915_READ(IIR);
>
> for (;;) {
> @@ -4504,6 +4525,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv)
> drm_irq_uninstall(dev_priv->dev);
> intel_hpd_cancel_work(dev_priv);
> dev_priv->pm.irqs_enabled = false;
> + synchronize_irq(dev_priv->dev->irq);
drm_irq_uninstall calls free_irq which means there's no way at all for our
handler to still run. The synchronize_irq here is hence redundnant. With
that hunk removed this is
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> }
>
> /**
> @@ -4517,6 +4539,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
> {
> dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
> dev_priv->pm.irqs_enabled = false;
> + synchronize_irq(dev_priv->dev->irq);
> }
>
> /**
> --
> 2.1.0
>
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
` (2 preceding siblings ...)
2015-02-23 14:31 ` [PATCH v3] " Imre Deak
@ 2015-02-24 9:14 ` Imre Deak
2015-02-24 9:29 ` Chris Wilson
2015-02-24 14:00 ` Jani Nikula
3 siblings, 2 replies; 15+ messages in thread
From: Imre Deak @ 2015-02-24 9:14 UTC (permalink / raw)
To: intel-gfx; +Cc: Jani Nikula, Klaus Ethgen, Daniel Vetter
Atm, it's possible that the interrupt handler is called when the device
is in D3 or some other low-power state. It can be due to another device
that is still in D0 state and shares the interrupt line with i915, or on
some platforms there could be spurious interrupts even without sharing
the interrupt line. The latter case was reported by Klaus Ethgen using a
Lenovo x61p machine (gen 4). He noticed this issue via a system
suspend/resume hang and bisected it to the following commit:
commit e11aa362308f5de467ce355a2a2471321b15a35c
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Wed Jun 18 09:52:55 2014 -0700
drm/i915: use runtime irq suspend/resume in freeze/thaw
This is a problem, since in low-power states IIR will always read
0xffffffff resulting in an endless IRQ servicing loop.
Fix this by handling interrupts only when the driver explicitly enables
them and so it's guaranteed that the interrupt registers return a valid
value.
Note that this issue existed even before the above commit, since during
runtime suspend/resume we never unregistered the handler.
v2:
- clarify the purpose of smp_mb() vs. synchronize_irq() in the
code comment (Chris)
v3:
- no need for an explicit smp_mb(), we can assume that synchronize_irq()
and the mmio read/writes in the install hooks provide for this (Daniel)
- remove code comment as the remaining synchronize_irq() is self
explanatory (Daniel)
v4:
- drm_irq_uninstall() implies synchronize_irq(), so no need to call it
explicitly (Daniel)
Reference: https://lkml.org/lkml/2015/2/11/205
Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_irq.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9073119..1561248 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
while (true) {
/* Find, clear, then process each source of interrupt */
@@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
for (;;) {
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
iir = I915_READ(VLV_IIR);
@@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
/* We get interrupts on unclaimed registers, so check for this before we
* do any I915_{READ,WRITE}. */
intel_uncore_check_errors(dev);
@@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
if (IS_GEN9(dev))
aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ16(IIR);
if (iir == 0)
return IRQ_NONE;
@@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
do {
bool irq_received = (iir & ~flip_mask) != 0;
@@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+ if (!intel_irqs_enabled(dev_priv))
+ return IRQ_NONE;
+
iir = I915_READ(IIR);
for (;;) {
@@ -4517,6 +4538,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
{
dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
dev_priv->pm.irqs_enabled = false;
+ synchronize_irq(dev_priv->dev->irq);
}
/**
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-24 9:14 ` [PATCH v4] " Imre Deak
@ 2015-02-24 9:29 ` Chris Wilson
2015-02-24 10:42 ` Daniel Vetter
2015-02-24 14:00 ` Jani Nikula
1 sibling, 1 reply; 15+ messages in thread
From: Chris Wilson @ 2015-02-24 9:29 UTC (permalink / raw)
To: Imre Deak; +Cc: Jani Nikula, Klaus Ethgen, intel-gfx, Daniel Vetter
On Tue, Feb 24, 2015 at 11:14:30AM +0200, Imre Deak wrote:
> Atm, it's possible that the interrupt handler is called when the device
> is in D3 or some other low-power state. It can be due to another device
> that is still in D0 state and shares the interrupt line with i915, or on
> some platforms there could be spurious interrupts even without sharing
> the interrupt line. The latter case was reported by Klaus Ethgen using a
> Lenovo x61p machine (gen 4). He noticed this issue via a system
> suspend/resume hang and bisected it to the following commit:
>
> commit e11aa362308f5de467ce355a2a2471321b15a35c
> Author: Jesse Barnes <jbarnes@virtuousgeek.org>
> Date: Wed Jun 18 09:52:55 2014 -0700
>
> drm/i915: use runtime irq suspend/resume in freeze/thaw
>
> This is a problem, since in low-power states IIR will always read
> 0xffffffff resulting in an endless IRQ servicing loop.
>
> Fix this by handling interrupts only when the driver explicitly enables
> them and so it's guaranteed that the interrupt registers return a valid
> value.
>
> Note that this issue existed even before the above commit, since during
> runtime suspend/resume we never unregistered the handler.
>
> v2:
> - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> code comment (Chris)
>
> v3:
> - no need for an explicit smp_mb(), we can assume that synchronize_irq()
> and the mmio read/writes in the install hooks provide for this (Daniel)
> - remove code comment as the remaining synchronize_irq() is self
> explanatory (Daniel)
Why make the assumption though? I thought the comments documenting the
interaction between the irq enablements, the irq handler and shared
interrupts was beneficial. At the very least the assumption should be
made explicit through comments in the code - because I am not convinced
that a cached write will be flushed by an uncached write to another area
of memory. In particular, note that on the gen most troubled by rogue
irqs (gen4), we do not have any memory barriers in the mmio paths.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-24 9:29 ` Chris Wilson
@ 2015-02-24 10:42 ` Daniel Vetter
2015-02-24 11:00 ` Chris Wilson
0 siblings, 1 reply; 15+ messages in thread
From: Daniel Vetter @ 2015-02-24 10:42 UTC (permalink / raw)
To: Chris Wilson, Imre Deak, intel-gfx, Klaus Ethgen, Dave Gordon,
Jani Nikula, Daniel Vetter
On Tue, Feb 24, 2015 at 09:29:15AM +0000, Chris Wilson wrote:
> On Tue, Feb 24, 2015 at 11:14:30AM +0200, Imre Deak wrote:
> > Atm, it's possible that the interrupt handler is called when the device
> > is in D3 or some other low-power state. It can be due to another device
> > that is still in D0 state and shares the interrupt line with i915, or on
> > some platforms there could be spurious interrupts even without sharing
> > the interrupt line. The latter case was reported by Klaus Ethgen using a
> > Lenovo x61p machine (gen 4). He noticed this issue via a system
> > suspend/resume hang and bisected it to the following commit:
> >
> > commit e11aa362308f5de467ce355a2a2471321b15a35c
> > Author: Jesse Barnes <jbarnes@virtuousgeek.org>
> > Date: Wed Jun 18 09:52:55 2014 -0700
> >
> > drm/i915: use runtime irq suspend/resume in freeze/thaw
> >
> > This is a problem, since in low-power states IIR will always read
> > 0xffffffff resulting in an endless IRQ servicing loop.
> >
> > Fix this by handling interrupts only when the driver explicitly enables
> > them and so it's guaranteed that the interrupt registers return a valid
> > value.
> >
> > Note that this issue existed even before the above commit, since during
> > runtime suspend/resume we never unregistered the handler.
> >
> > v2:
> > - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> > code comment (Chris)
> >
> > v3:
> > - no need for an explicit smp_mb(), we can assume that synchronize_irq()
> > and the mmio read/writes in the install hooks provide for this (Daniel)
> > - remove code comment as the remaining synchronize_irq() is self
> > explanatory (Daniel)
>
> Why make the assumption though? I thought the comments documenting the
> interaction between the irq enablements, the irq handler and shared
> interrupts was beneficial. At the very least the assumption should be
> made explicit through comments in the code - because I am not convinced
> that a cached write will be flushed by an uncached write to another area
> of memory. In particular, note that on the gen most troubled by rogue
> irqs (gen4), we do not have any memory barriers in the mmio paths.
The synchronize_irq is a fairly massive barrier and I've figured the name
is descriptive enough to make clear what's going on. At least I've felt
any comment on top would be redundant.
Also the hard rule for adding comments to explicit barriers is mostly a
reminder that you always need barriers on both sides, and the comment
then must explain where the other side is in the code. Imo with
synchronize_irq it's clear that the other side is the irq handler already.
What do you want to clarify on top of that in the comment?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-24 10:42 ` Daniel Vetter
@ 2015-02-24 11:00 ` Chris Wilson
0 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2015-02-24 11:00 UTC (permalink / raw)
To: Daniel Vetter; +Cc: Jani Nikula, Klaus Ethgen, Daniel Vetter, intel-gfx
On Tue, Feb 24, 2015 at 11:42:20AM +0100, Daniel Vetter wrote:
> On Tue, Feb 24, 2015 at 09:29:15AM +0000, Chris Wilson wrote:
> > On Tue, Feb 24, 2015 at 11:14:30AM +0200, Imre Deak wrote:
> > > Atm, it's possible that the interrupt handler is called when the device
> > > is in D3 or some other low-power state. It can be due to another device
> > > that is still in D0 state and shares the interrupt line with i915, or on
> > > some platforms there could be spurious interrupts even without sharing
> > > the interrupt line. The latter case was reported by Klaus Ethgen using a
> > > Lenovo x61p machine (gen 4). He noticed this issue via a system
> > > suspend/resume hang and bisected it to the following commit:
> > >
> > > commit e11aa362308f5de467ce355a2a2471321b15a35c
> > > Author: Jesse Barnes <jbarnes@virtuousgeek.org>
> > > Date: Wed Jun 18 09:52:55 2014 -0700
> > >
> > > drm/i915: use runtime irq suspend/resume in freeze/thaw
> > >
> > > This is a problem, since in low-power states IIR will always read
> > > 0xffffffff resulting in an endless IRQ servicing loop.
> > >
> > > Fix this by handling interrupts only when the driver explicitly enables
> > > them and so it's guaranteed that the interrupt registers return a valid
> > > value.
> > >
> > > Note that this issue existed even before the above commit, since during
> > > runtime suspend/resume we never unregistered the handler.
> > >
> > > v2:
> > > - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> > > code comment (Chris)
> > >
> > > v3:
> > > - no need for an explicit smp_mb(), we can assume that synchronize_irq()
> > > and the mmio read/writes in the install hooks provide for this (Daniel)
> > > - remove code comment as the remaining synchronize_irq() is self
> > > explanatory (Daniel)
> >
> > Why make the assumption though? I thought the comments documenting the
> > interaction between the irq enablements, the irq handler and shared
> > interrupts was beneficial. At the very least the assumption should be
> > made explicit through comments in the code - because I am not convinced
> > that a cached write will be flushed by an uncached write to another area
> > of memory. In particular, note that on the gen most troubled by rogue
> > irqs (gen4), we do not have any memory barriers in the mmio paths.
>
> The synchronize_irq is a fairly massive barrier and I've figured the name
> is descriptive enough to make clear what's going on. At least I've felt
> any comment on top would be redundant.
>
> Also the hard rule for adding comments to explicit barriers is mostly a
> reminder that you always need barriers on both sides, and the comment
> then must explain where the other side is in the code. Imo with
> synchronize_irq it's clear that the other side is the irq handler already.
>
> What do you want to clarify on top of that in the comment?
The smp_mb() was being applied to the enable path, not the disable +
sync_irq path. Also we now have a large body of lore regarding interrupt
issues on gen4 but we haven't been documenting any of it. At the bare
minimum we need to explain why we call sync_irq and how that interacts
with the intel_irqs_enabled() checks and shared interrupts.
Even perhaps adding intel_runtime_pm_enabled_irq() as a wrapper for the
irq handlers to cross-reference against the runtime_pm tricks -
otherwise, there is a good likelihood that in the years to come, we
might forget how we end up inside a disabled interrupt handler and why
we are not allowed to touch the hardware at that point.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-23 14:31 ` [PATCH v3] " Imre Deak
2015-02-24 0:07 ` Daniel Vetter
@ 2015-02-24 13:56 ` shuang.he
1 sibling, 0 replies; 15+ messages in thread
From: shuang.he @ 2015-02-24 13:56 UTC (permalink / raw)
To: shuang.he, ethan.gao, intel-gfx, imre.deak
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5812
-------------------------------------Summary-------------------------------------
Platform Delta drm-intel-nightly Series Applied
PNV -2 281/281 279/281
ILK 308/308 308/308
SNB 326/326 326/326
IVB 380/380 380/380
BYT 294/294 294/294
HSW 421/421 421/421
BDW -1 316/316 315/316
-------------------------------------Detailed-------------------------------------
Platform Test drm-intel-nightly Series Applied
*PNV igt_gem_userptr_blits_minor-unsync-interruptible PASS(2) DMESG_WARN(1)PASS(1)
PNV igt_gem_userptr_blits_minor-unsync-normal DMESG_WARN(1)PASS(1) DMESG_WARN(1)PASS(1)
*BDW igt_gem_gtt_hog PASS(5) DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states
2015-02-24 9:14 ` [PATCH v4] " Imre Deak
2015-02-24 9:29 ` Chris Wilson
@ 2015-02-24 14:00 ` Jani Nikula
1 sibling, 0 replies; 15+ messages in thread
From: Jani Nikula @ 2015-02-24 14:00 UTC (permalink / raw)
To: Imre Deak, intel-gfx; +Cc: Daniel Vetter, Klaus Ethgen
On Tue, 24 Feb 2015, Imre Deak <imre.deak@intel.com> wrote:
> Atm, it's possible that the interrupt handler is called when the device
> is in D3 or some other low-power state. It can be due to another device
> that is still in D0 state and shares the interrupt line with i915, or on
> some platforms there could be spurious interrupts even without sharing
> the interrupt line. The latter case was reported by Klaus Ethgen using a
> Lenovo x61p machine (gen 4). He noticed this issue via a system
> suspend/resume hang and bisected it to the following commit:
>
> commit e11aa362308f5de467ce355a2a2471321b15a35c
> Author: Jesse Barnes <jbarnes@virtuousgeek.org>
> Date: Wed Jun 18 09:52:55 2014 -0700
>
> drm/i915: use runtime irq suspend/resume in freeze/thaw
>
> This is a problem, since in low-power states IIR will always read
> 0xffffffff resulting in an endless IRQ servicing loop.
>
> Fix this by handling interrupts only when the driver explicitly enables
> them and so it's guaranteed that the interrupt registers return a valid
> value.
>
> Note that this issue existed even before the above commit, since during
> runtime suspend/resume we never unregistered the handler.
>
> v2:
> - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> code comment (Chris)
>
> v3:
> - no need for an explicit smp_mb(), we can assume that synchronize_irq()
> and the mmio read/writes in the install hooks provide for this (Daniel)
> - remove code comment as the remaining synchronize_irq() is self
> explanatory (Daniel)
>
> v4:
> - drm_irq_uninstall() implies synchronize_irq(), so no need to call it
> explicitly (Daniel)
>
> Reference: https://lkml.org/lkml/2015/2/11/205
> Reported-and-bisected-by: Klaus Ethgen <Klaus@Ethgen.ch>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Pushed to drm-intel-fixes, cc: stable, thanks for the patch and review.
BR,
Jani.
> ---
> drivers/gpu/drm/i915/i915_irq.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 9073119..1561248 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
> u32 iir, gt_iir, pm_iir;
> irqreturn_t ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> while (true) {
> /* Find, clear, then process each source of interrupt */
>
> @@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
> u32 master_ctl, iir;
> irqreturn_t ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> for (;;) {
> master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
> iir = I915_READ(VLV_IIR);
> @@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
> u32 de_iir, gt_iir, de_ier, sde_ier = 0;
> irqreturn_t ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> /* We get interrupts on unclaimed registers, so check for this before we
> * do any I915_{READ,WRITE}. */
> intel_uncore_check_errors(dev);
> @@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
> enum pipe pipe;
> u32 aux_mask = GEN8_AUX_CHANNEL_A;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> if (IS_GEN9(dev))
> aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
> GEN9_AUX_CHANNEL_D;
> @@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
> I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
> I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> iir = I915_READ16(IIR);
> if (iir == 0)
> return IRQ_NONE;
> @@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
> I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
> int pipe, ret = IRQ_NONE;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> iir = I915_READ(IIR);
> do {
> bool irq_received = (iir & ~flip_mask) != 0;
> @@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
> I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
> I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
> iir = I915_READ(IIR);
>
> for (;;) {
> @@ -4517,6 +4538,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv)
> {
> dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
> dev_priv->pm.irqs_enabled = false;
> + synchronize_irq(dev_priv->dev->irq);
> }
>
> /**
> --
> 2.1.0
>
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-02-24 13:59 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-20 19:09 [PATCH] drm/i915: avoid processing spurious/shared interrupts in low-power states Imre Deak
2015-02-20 19:40 ` Chris Wilson
2015-02-20 19:53 ` Imre Deak
2015-02-20 22:26 ` shuang.he
2015-02-23 9:58 ` [PATCH v2] " Imre Deak
2015-02-23 11:57 ` Chris Wilson
2015-02-23 14:26 ` shuang.he
2015-02-23 14:31 ` [PATCH v3] " Imre Deak
2015-02-24 0:07 ` Daniel Vetter
2015-02-24 13:56 ` shuang.he
2015-02-24 9:14 ` [PATCH v4] " Imre Deak
2015-02-24 9:29 ` Chris Wilson
2015-02-24 10:42 ` Daniel Vetter
2015-02-24 11:00 ` Chris Wilson
2015-02-24 14:00 ` Jani Nikula
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox