diff mbox series

[v2] drm/i915: clear error registers after error capture

Message ID 20180830111507.7859-1-lionel.g.landwerlin@intel.com (mailing list archive)
State New, archived
Headers show
Series [v2] drm/i915: clear error registers after error capture | expand

Commit Message

Lionel Landwerlin Aug. 30, 2018, 11:15 a.m. UTC
We need to clear the register in order to get correct value after the
next potential hang.

v2: Centralize error register clearing in i915_irq.c (Chris)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     |  2 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c | 18 ++++++------------
 drivers/gpu/drm/i915/i915_irq.c     | 18 +++++++++++++++++-
 3 files changed, 25 insertions(+), 13 deletions(-)

Comments

Chris Wilson Aug. 30, 2018, 11:23 a.m. UTC | #1
Quoting Lionel Landwerlin (2018-08-30 12:15:07)
> We need to clear the register in order to get correct value after the
> next potential hang.
> 
> v2: Centralize error register clearing in i915_irq.c (Chris)
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

Ok, I was thinking of move the code around the files a bit more, but
agree with what you've done as being the smallest change possible.

> @@ -3238,6 +3238,22 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
>                 I915_WRITE(EMR, I915_READ(EMR) | eir);
>                 I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT);
>         }
> +
> +       if (INTEL_GEN(dev_priv) < 8) {
> +               struct intel_engine_cs *engine;
> +               enum intel_engine_id id;
> +
> +               for_each_engine(engine, dev_priv, id) {
> +                       I915_WRITE(RING_FAULT_REG(engine),
> +                                  I915_READ(RING_FAULT_REG(engine)) &
> +                                  ~RING_FAULT_VALID);
> +               }
> +               POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));

Memory says this is gen6+, and i915_gpu_error.c has the same opinion.

> +       } else {
> +               I915_WRITE(GEN8_RING_FAULT_REG,
> +                          I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID);
> +               POSTING_READ(GEN8_RING_FAULT_REG);
> +       }

I think you want:

	if (INTEL_GEN > 8) {
		...
	} else if (INTEL_GEN > 6) {
		...
	} else {
		/* Are there any fault regs for earlier? */
	}

With that tweak,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
Lionel Landwerlin Aug. 30, 2018, 11:41 a.m. UTC | #2
On 30/08/2018 12:23, Chris Wilson wrote:
> Quoting Lionel Landwerlin (2018-08-30 12:15:07)
>> We need to clear the register in order to get correct value after the
>> next potential hang.
>>
>> v2: Centralize error register clearing in i915_irq.c (Chris)
>>
>> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Ok, I was thinking of move the code around the files a bit more, but
> agree with what you've done as being the smallest change possible.


If you have a suggestion, I can do a v3.


>
>> @@ -3238,6 +3238,22 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
>>                  I915_WRITE(EMR, I915_READ(EMR) | eir);
>>                  I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT);
>>          }
>> +
>> +       if (INTEL_GEN(dev_priv) < 8) {
>> +               struct intel_engine_cs *engine;
>> +               enum intel_engine_id id;
>> +
>> +               for_each_engine(engine, dev_priv, id) {
>> +                       I915_WRITE(RING_FAULT_REG(engine),
>> +                                  I915_READ(RING_FAULT_REG(engine)) &
>> +                                  ~RING_FAULT_VALID);
>> +               }
>> +               POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
> Memory says this is gen6+, and i915_gpu_error.c has the same opinion.


What is? The post read?


>
>> +       } else {
>> +               I915_WRITE(GEN8_RING_FAULT_REG,
>> +                          I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID);
>> +               POSTING_READ(GEN8_RING_FAULT_REG);
>> +       }
> I think you want:
>
> 	if (INTEL_GEN > 8) {
> 		...
> 	} else if (INTEL_GEN > 6) {
> 		...
> 	} else {
> 		/* Are there any fault regs for earlier? */
> 	}
>
> With that tweak,


Thanks, done locally.


> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> -Chris
>
Chris Wilson Aug. 30, 2018, 11:45 a.m. UTC | #3
Quoting Lionel Landwerlin (2018-08-30 12:41:42)
> On 30/08/2018 12:23, Chris Wilson wrote:
> > Quoting Lionel Landwerlin (2018-08-30 12:15:07)
> >> We need to clear the register in order to get correct value after the
> >> next potential hang.
> >>
> >> v2: Centralize error register clearing in i915_irq.c (Chris)
> >>
> >> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > Ok, I was thinking of move the code around the files a bit more, but
> > agree with what you've done as being the smallest change possible.
> 
> 
> If you have a suggestion, I can do a v3.

Basically pulling the fault reg out of i915_gem_gtt.c and everything
into i915_reset.c. And then removing the struct_mutex.

> >> @@ -3238,6 +3238,22 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
> >>                  I915_WRITE(EMR, I915_READ(EMR) | eir);
> >>                  I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT);
> >>          }
> >> +
> >> +       if (INTEL_GEN(dev_priv) < 8) {
> >> +               struct intel_engine_cs *engine;
> >> +               enum intel_engine_id id;
> >> +
> >> +               for_each_engine(engine, dev_priv, id) {
> >> +                       I915_WRITE(RING_FAULT_REG(engine),
> >> +                                  I915_READ(RING_FAULT_REG(engine)) &
> >> +                                  ~RING_FAULT_VALID);
> >> +               }
> >> +               POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
> > Memory says this is gen6+, and i915_gpu_error.c has the same opinion.
> 
> 
> What is? The post read?
The comment below :)

> >> +       } else {
> >> +               I915_WRITE(GEN8_RING_FAULT_REG,
> >> +                          I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID);
> >> +               POSTING_READ(GEN8_RING_FAULT_REG);
> >> +       }
> > I think you want:
> >
> >       if (INTEL_GEN > 8) {
> >               ...
> >       } else if (INTEL_GEN > 6) {
> >               ...
> >       } else {
> >               /* Are there any fault regs for earlier? */
> >       }
> >
> > With that tweak,
> 
> 
> Thanks, done locally.

Hopefully with >= :)
-Chris
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 40c93a37e385..34cca15be926 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2817,6 +2817,8 @@  extern void intel_irq_fini(struct drm_i915_private *dev_priv);
 int intel_irq_install(struct drm_i915_private *dev_priv);
 void intel_irq_uninstall(struct drm_i915_private *dev_priv);
 
+void i915_clear_error_registers(struct drm_i915_private *dev_priv);
+
 static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
 {
 	return dev_priv->gvt;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 4137af4bd8f5..d9d44639ba26 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2337,7 +2337,7 @@  static bool needs_idle_maps(struct drm_i915_private *dev_priv)
 	return IS_GEN5(dev_priv) && IS_MOBILE(dev_priv) && intel_vtd_active();
 }
 
-static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv)
+static void gen6_check_faults(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
@@ -2355,15 +2355,11 @@  static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv)
 					 fault & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT",
 					 RING_FAULT_SRCID(fault),
 					 RING_FAULT_FAULT_TYPE(fault));
-			I915_WRITE(RING_FAULT_REG(engine),
-				   fault & ~RING_FAULT_VALID);
 		}
 	}
-
-	POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
 }
 
-static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv)
+static void gen8_check_faults(struct drm_i915_private *dev_priv)
 {
 	u32 fault = I915_READ(GEN8_RING_FAULT_REG);
 
@@ -2388,22 +2384,20 @@  static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv)
 				 GEN8_RING_FAULT_ENGINE_ID(fault),
 				 RING_FAULT_SRCID(fault),
 				 RING_FAULT_FAULT_TYPE(fault));
-		I915_WRITE(GEN8_RING_FAULT_REG,
-			   fault & ~RING_FAULT_VALID);
 	}
-
-	POSTING_READ(GEN8_RING_FAULT_REG);
 }
 
 void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
 {
 	/* From GEN8 onwards we only have one 'All Engine Fault Register' */
 	if (INTEL_GEN(dev_priv) >= 8)
-		gen8_check_and_clear_faults(dev_priv);
+		gen8_check_faults(dev_priv);
 	else if (INTEL_GEN(dev_priv) >= 6)
-		gen6_check_and_clear_faults(dev_priv);
+		gen6_check_faults(dev_priv);
 	else
 		return;
+
+	i915_clear_error_registers(dev_priv);
 }
 
 void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8084e35b25c5..61a01584eae2 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3215,7 +3215,7 @@  static void i915_reset_device(struct drm_i915_private *dev_priv,
 		kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event);
 }
 
-static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
+void i915_clear_error_registers(struct drm_i915_private *dev_priv)
 {
 	u32 eir;
 
@@ -3238,6 +3238,22 @@  static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
 		I915_WRITE(EMR, I915_READ(EMR) | eir);
 		I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT);
 	}
+
+	if (INTEL_GEN(dev_priv) < 8) {
+		struct intel_engine_cs *engine;
+		enum intel_engine_id id;
+
+		for_each_engine(engine, dev_priv, id) {
+			I915_WRITE(RING_FAULT_REG(engine),
+				   I915_READ(RING_FAULT_REG(engine)) &
+				   ~RING_FAULT_VALID);
+		}
+		POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
+	} else {
+		I915_WRITE(GEN8_RING_FAULT_REG,
+			   I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID);
+		POSTING_READ(GEN8_RING_FAULT_REG);
+	}
 }
 
 /**