Re: [Intel-gfx] [PATCH 01/40] drm/i915/hangcheck: Replace hangcheck.seqno with RING_HEAD

2019-05-08 Thread Chris Wilson
Quoting Mika Kuoppala (2019-05-08 15:00:11)
> Chris Wilson  writes:
> 
> > Quoting Mika Kuoppala (2019-05-08 13:30:46)
> >> Chris Wilson  writes:
> >> 
> >> > After realising we need to sample RING_START to detect context switches
> >> > from preemption events that do not allow for the seqno to advance, we
> >> > can also realise that the seqno itself is just a distance along the ring
> >> > and so can be replaced by sampling RING_HEAD.
> >> >
> >> > Signed-off-by: Chris Wilson 
> >> > Cc: Mika Kuoppala 
> >> > ---
> >> >  static enum intel_engine_hangcheck_action
> >> > @@ -156,7 +156,7 @@ hangcheck_get_action(struct intel_engine_cs *engine,
> >> >   if (engine->hangcheck.last_ring != hc->ring)
> >> >   return ENGINE_ACTIVE_SEQNO;
> >> >  
> >> > - if (engine->hangcheck.last_seqno != hc->seqno)
> >> > + if (engine->hangcheck.last_head != hc->head)
> >> >   return ENGINE_ACTIVE_SEQNO;
> >> 
> >> Change the enum also?
> >
> > Pffifle. As far as hangcheck goes RING_START:RING_HEAD comprise its
> > seqno.
> >
> > Makes for a good talking point in a few years time :)
> 
> Fair enough.
> 
> >
> >> > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
> >> > b/drivers/gpu/drm/i915/gt/intel_lrc.c
> >> > index d1a54d2c3d5d..f1d62746e066 100644
> >> > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> >> > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> >> > @@ -2275,12 +2275,6 @@ static u32 *gen8_emit_fini_breadcrumb(struct 
> >> > i915_request *request, u32 *cs)
> >> > request->timeline->hwsp_offset,
> >> > 0);
> >> >  
> >> > - cs = gen8_emit_ggtt_write(cs,
> >> > -   
> >> > intel_engine_next_hangcheck_seqno(request->engine),
> >> > -   I915_GEM_HWS_HANGCHECK_ADDR,
> >> > -   MI_FLUSH_DW_STORE_INDEX);
> >> > -
> >> > -
> >> >   *cs++ = MI_USER_INTERRUPT;
> >> >   *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
> >> >  
> >> > @@ -2297,14 +2291,11 @@ static u32 *gen8_emit_fini_breadcrumb_rcs(struct 
> >> > i915_request *request, u32 *cs)
> >> > request->timeline->hwsp_offset,
> >> > 
> >> > PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
> >> > PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> >> > -   PIPE_CONTROL_DC_FLUSH_ENABLE |
> >> > -   PIPE_CONTROL_FLUSH_ENABLE |
> >> > -   PIPE_CONTROL_CS_STALL);
> >> 
> >> ???
> >
> > Kabylake sends the interrupt too early otherwise. The hangcheck write
> > saved us by pure accident.
> 
> I read the diff wrong at first try also, was concerned that we lost cs stall.
> Regardless this could benefit from a comment explaining the need to
> force sync for the intr.

Indeed, that is sensible since it's an empirical result and worth
validating again later. Done and pushed, thanks.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH 01/40] drm/i915/hangcheck: Replace hangcheck.seqno with RING_HEAD

2019-05-08 Thread Mika Kuoppala
Chris Wilson  writes:

> Quoting Mika Kuoppala (2019-05-08 13:30:46)
>> Chris Wilson  writes:
>> 
>> > After realising we need to sample RING_START to detect context switches
>> > from preemption events that do not allow for the seqno to advance, we
>> > can also realise that the seqno itself is just a distance along the ring
>> > and so can be replaced by sampling RING_HEAD.
>> >
>> > Signed-off-by: Chris Wilson 
>> > Cc: Mika Kuoppala 
>> > ---
>> >  static enum intel_engine_hangcheck_action
>> > @@ -156,7 +156,7 @@ hangcheck_get_action(struct intel_engine_cs *engine,
>> >   if (engine->hangcheck.last_ring != hc->ring)
>> >   return ENGINE_ACTIVE_SEQNO;
>> >  
>> > - if (engine->hangcheck.last_seqno != hc->seqno)
>> > + if (engine->hangcheck.last_head != hc->head)
>> >   return ENGINE_ACTIVE_SEQNO;
>> 
>> Change the enum also?
>
> Pffifle. As far as hangcheck goes RING_START:RING_HEAD comprise its
> seqno.
>
> Makes for a good talking point in a few years time :)

Fair enough.

>
>> > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
>> > b/drivers/gpu/drm/i915/gt/intel_lrc.c
>> > index d1a54d2c3d5d..f1d62746e066 100644
>> > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
>> > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
>> > @@ -2275,12 +2275,6 @@ static u32 *gen8_emit_fini_breadcrumb(struct 
>> > i915_request *request, u32 *cs)
>> > request->timeline->hwsp_offset,
>> > 0);
>> >  
>> > - cs = gen8_emit_ggtt_write(cs,
>> > -   
>> > intel_engine_next_hangcheck_seqno(request->engine),
>> > -   I915_GEM_HWS_HANGCHECK_ADDR,
>> > -   MI_FLUSH_DW_STORE_INDEX);
>> > -
>> > -
>> >   *cs++ = MI_USER_INTERRUPT;
>> >   *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
>> >  
>> > @@ -2297,14 +2291,11 @@ static u32 *gen8_emit_fini_breadcrumb_rcs(struct 
>> > i915_request *request, u32 *cs)
>> > request->timeline->hwsp_offset,
>> > PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH 
>> > |
>> > PIPE_CONTROL_DEPTH_CACHE_FLUSH |
>> > -   PIPE_CONTROL_DC_FLUSH_ENABLE |
>> > -   PIPE_CONTROL_FLUSH_ENABLE |
>> > -   PIPE_CONTROL_CS_STALL);
>> 
>> ???
>
> Kabylake sends the interrupt too early otherwise. The hangcheck write
> saved us by pure accident.

I read the diff wrong at first try also, was concerned that we lost cs stall.
Regardless this could benefit from a comment explaining the need to
force sync for the intr.

Was happy to see measure_breadcrumb_dw() paying off. Also leaning to
it for alignment forcing.

Reviewed-by: Mika Kuoppala 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH 01/40] drm/i915/hangcheck: Replace hangcheck.seqno with RING_HEAD

2019-05-08 Thread Chris Wilson
Quoting Mika Kuoppala (2019-05-08 13:30:46)
> Chris Wilson  writes:
> 
> > After realising we need to sample RING_START to detect context switches
> > from preemption events that do not allow for the seqno to advance, we
> > can also realise that the seqno itself is just a distance along the ring
> > and so can be replaced by sampling RING_HEAD.
> >
> > Signed-off-by: Chris Wilson 
> > Cc: Mika Kuoppala 
> > ---
> >  static enum intel_engine_hangcheck_action
> > @@ -156,7 +156,7 @@ hangcheck_get_action(struct intel_engine_cs *engine,
> >   if (engine->hangcheck.last_ring != hc->ring)
> >   return ENGINE_ACTIVE_SEQNO;
> >  
> > - if (engine->hangcheck.last_seqno != hc->seqno)
> > + if (engine->hangcheck.last_head != hc->head)
> >   return ENGINE_ACTIVE_SEQNO;
> 
> Change the enum also?

Pffifle. As far as hangcheck goes RING_START:RING_HEAD comprise its
seqno.

Makes for a good talking point in a few years time :)

> > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
> > b/drivers/gpu/drm/i915/gt/intel_lrc.c
> > index d1a54d2c3d5d..f1d62746e066 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> > @@ -2275,12 +2275,6 @@ static u32 *gen8_emit_fini_breadcrumb(struct 
> > i915_request *request, u32 *cs)
> > request->timeline->hwsp_offset,
> > 0);
> >  
> > - cs = gen8_emit_ggtt_write(cs,
> > -   
> > intel_engine_next_hangcheck_seqno(request->engine),
> > -   I915_GEM_HWS_HANGCHECK_ADDR,
> > -   MI_FLUSH_DW_STORE_INDEX);
> > -
> > -
> >   *cs++ = MI_USER_INTERRUPT;
> >   *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
> >  
> > @@ -2297,14 +2291,11 @@ static u32 *gen8_emit_fini_breadcrumb_rcs(struct 
> > i915_request *request, u32 *cs)
> > request->timeline->hwsp_offset,
> > PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
> > PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> > -   PIPE_CONTROL_DC_FLUSH_ENABLE |
> > -   PIPE_CONTROL_FLUSH_ENABLE |
> > -   PIPE_CONTROL_CS_STALL);
> 
> ???

Kabylake sends the interrupt too early otherwise. The hangcheck write
saved us by pure accident.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Re: [Intel-gfx] [PATCH 01/40] drm/i915/hangcheck: Replace hangcheck.seqno with RING_HEAD

2019-05-08 Thread Mika Kuoppala
Chris Wilson  writes:

> After realising we need to sample RING_START to detect context switches
> from preemption events that do not allow for the seqno to advance, we
> can also realise that the seqno itself is just a distance along the ring
> and so can be replaced by sampling RING_HEAD.
>
> Signed-off-by: Chris Wilson 
> Cc: Mika Kuoppala 
> ---
>  drivers/gpu/drm/i915/gt/intel_engine.h   | 15 -
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c|  5 ++-
>  drivers/gpu/drm/i915/gt/intel_engine_types.h |  3 +-
>  drivers/gpu/drm/i915/gt/intel_hangcheck.c|  8 ++---
>  drivers/gpu/drm/i915/gt/intel_lrc.c  | 19 +++-
>  drivers/gpu/drm/i915/gt/intel_ringbuffer.c   | 32 ++--
>  drivers/gpu/drm/i915/i915_debugfs.c  | 12 ++--
>  7 files changed, 17 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
> b/drivers/gpu/drm/i915/gt/intel_engine.h
> index 06d785533502..9359b3a7ad9c 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine.h
> @@ -215,8 +215,6 @@ intel_write_status_page(struct intel_engine_cs *engine, 
> int reg, u32 value)
>   */
>  #define I915_GEM_HWS_PREEMPT 0x32
>  #define I915_GEM_HWS_PREEMPT_ADDR(I915_GEM_HWS_PREEMPT * sizeof(u32))
> -#define I915_GEM_HWS_HANGCHECK   0x34
> -#define I915_GEM_HWS_HANGCHECK_ADDR  (I915_GEM_HWS_HANGCHECK * sizeof(u32))
>  #define I915_GEM_HWS_SEQNO   0x40
>  #define I915_GEM_HWS_SEQNO_ADDR  (I915_GEM_HWS_SEQNO * 
> sizeof(u32))
>  #define I915_GEM_HWS_SCRATCH 0x80
> @@ -548,17 +546,4 @@ static inline bool inject_preempt_hang(struct 
> intel_engine_execlists *execlists)
>  
>  #endif
>  
> -static inline u32
> -intel_engine_next_hangcheck_seqno(struct intel_engine_cs *engine)
> -{
> - return engine->hangcheck.next_seqno =
> - next_pseudo_random32(engine->hangcheck.next_seqno);
> -}
> -
> -static inline u32
> -intel_engine_get_hangcheck_seqno(struct intel_engine_cs *engine)
> -{
> - return intel_read_status_page(engine, I915_GEM_HWS_HANGCHECK);
> -}
> -
>  #endif /* _INTEL_RINGBUFFER_H_ */
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> index 416d7e2e6f8c..4c3753c1b573 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> @@ -721,6 +721,7 @@ static int measure_breadcrumb_dw(struct intel_engine_cs 
> *engine)
>   goto out_timeline;
>  
>   dw = engine->emit_fini_breadcrumb(>rq, frame->cs) - frame->cs;
> + GEM_BUG_ON(dw & 1); /* RING_TAIL must be qword aligned */
>  
>   i915_timeline_unpin(>timeline);
>  
> @@ -1444,9 +1445,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
>   drm_printf(m, "*** WEDGED ***\n");
>  
>   drm_printf(m, "\tAwake? %d\n", atomic_read(>wakeref.count));
> - drm_printf(m, "\tHangcheck %x:%x [%d ms]\n",
> -engine->hangcheck.last_seqno,
> -engine->hangcheck.next_seqno,
> + drm_printf(m, "\tHangcheck: %d ms ago\n",
>  jiffies_to_msecs(jiffies - 
> engine->hangcheck.action_timestamp));
>   drm_printf(m, "\tReset count: %d (global %d)\n",
>  i915_reset_engine_count(error, engine),
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
> b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index c0ab11b12e14..e381c1c73902 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -54,8 +54,7 @@ struct intel_instdone {
>  struct intel_engine_hangcheck {
>   u64 acthd;
>   u32 last_ring;
> - u32 last_seqno;
> - u32 next_seqno;
> + u32 last_head;
>   unsigned long action_timestamp;
>   struct intel_instdone instdone;
>  };
> diff --git a/drivers/gpu/drm/i915/gt/intel_hangcheck.c 
> b/drivers/gpu/drm/i915/gt/intel_hangcheck.c
> index 721ab74a382f..3a4d09b80fa0 100644
> --- a/drivers/gpu/drm/i915/gt/intel_hangcheck.c
> +++ b/drivers/gpu/drm/i915/gt/intel_hangcheck.c
> @@ -28,7 +28,7 @@
>  struct hangcheck {
>   u64 acthd;
>   u32 ring;
> - u32 seqno;
> + u32 head;
>   enum intel_engine_hangcheck_action action;
>   unsigned long action_timestamp;
>   int deadlock;
> @@ -134,16 +134,16 @@ static void hangcheck_load_sample(struct 
> intel_engine_cs *engine,
> struct hangcheck *hc)
>  {
>   hc->acthd = intel_engine_get_active_head(engine);
> - hc->seqno = intel_engine_get_hangcheck_seqno(engine);
>   hc->ring = ENGINE_READ(engine, RING_START);
> + hc->head = ENGINE_READ(engine, RING_HEAD);
>  }
>  
>  static void hangcheck_store_sample(struct intel_engine_cs *engine,
>  const struct hangcheck *hc)
>  {
>   engine->hangcheck.acthd = hc->acthd;
> - engine->hangcheck.last_seqno = hc->seqno;
>   

[Intel-gfx] [PATCH 01/40] drm/i915/hangcheck: Replace hangcheck.seqno with RING_HEAD

2019-05-08 Thread Chris Wilson
After realising we need to sample RING_START to detect context switches
from preemption events that do not allow for the seqno to advance, we
can also realise that the seqno itself is just a distance along the ring
and so can be replaced by sampling RING_HEAD.

Signed-off-by: Chris Wilson 
Cc: Mika Kuoppala 
---
 drivers/gpu/drm/i915/gt/intel_engine.h   | 15 -
 drivers/gpu/drm/i915/gt/intel_engine_cs.c|  5 ++-
 drivers/gpu/drm/i915/gt/intel_engine_types.h |  3 +-
 drivers/gpu/drm/i915/gt/intel_hangcheck.c|  8 ++---
 drivers/gpu/drm/i915/gt/intel_lrc.c  | 19 +++-
 drivers/gpu/drm/i915/gt/intel_ringbuffer.c   | 32 ++--
 drivers/gpu/drm/i915/i915_debugfs.c  | 12 ++--
 7 files changed, 17 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index 06d785533502..9359b3a7ad9c 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -215,8 +215,6 @@ intel_write_status_page(struct intel_engine_cs *engine, int 
reg, u32 value)
  */
 #define I915_GEM_HWS_PREEMPT   0x32
 #define I915_GEM_HWS_PREEMPT_ADDR  (I915_GEM_HWS_PREEMPT * sizeof(u32))
-#define I915_GEM_HWS_HANGCHECK 0x34
-#define I915_GEM_HWS_HANGCHECK_ADDR(I915_GEM_HWS_HANGCHECK * sizeof(u32))
 #define I915_GEM_HWS_SEQNO 0x40
 #define I915_GEM_HWS_SEQNO_ADDR(I915_GEM_HWS_SEQNO * 
sizeof(u32))
 #define I915_GEM_HWS_SCRATCH   0x80
@@ -548,17 +546,4 @@ static inline bool inject_preempt_hang(struct 
intel_engine_execlists *execlists)
 
 #endif
 
-static inline u32
-intel_engine_next_hangcheck_seqno(struct intel_engine_cs *engine)
-{
-   return engine->hangcheck.next_seqno =
-   next_pseudo_random32(engine->hangcheck.next_seqno);
-}
-
-static inline u32
-intel_engine_get_hangcheck_seqno(struct intel_engine_cs *engine)
-{
-   return intel_read_status_page(engine, I915_GEM_HWS_HANGCHECK);
-}
-
 #endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 416d7e2e6f8c..4c3753c1b573 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -721,6 +721,7 @@ static int measure_breadcrumb_dw(struct intel_engine_cs 
*engine)
goto out_timeline;
 
dw = engine->emit_fini_breadcrumb(>rq, frame->cs) - frame->cs;
+   GEM_BUG_ON(dw & 1); /* RING_TAIL must be qword aligned */
 
i915_timeline_unpin(>timeline);
 
@@ -1444,9 +1445,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
drm_printf(m, "*** WEDGED ***\n");
 
drm_printf(m, "\tAwake? %d\n", atomic_read(>wakeref.count));
-   drm_printf(m, "\tHangcheck %x:%x [%d ms]\n",
-  engine->hangcheck.last_seqno,
-  engine->hangcheck.next_seqno,
+   drm_printf(m, "\tHangcheck: %d ms ago\n",
   jiffies_to_msecs(jiffies - 
engine->hangcheck.action_timestamp));
drm_printf(m, "\tReset count: %d (global %d)\n",
   i915_reset_engine_count(error, engine),
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index c0ab11b12e14..e381c1c73902 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -54,8 +54,7 @@ struct intel_instdone {
 struct intel_engine_hangcheck {
u64 acthd;
u32 last_ring;
-   u32 last_seqno;
-   u32 next_seqno;
+   u32 last_head;
unsigned long action_timestamp;
struct intel_instdone instdone;
 };
diff --git a/drivers/gpu/drm/i915/gt/intel_hangcheck.c 
b/drivers/gpu/drm/i915/gt/intel_hangcheck.c
index 721ab74a382f..3a4d09b80fa0 100644
--- a/drivers/gpu/drm/i915/gt/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/intel_hangcheck.c
@@ -28,7 +28,7 @@
 struct hangcheck {
u64 acthd;
u32 ring;
-   u32 seqno;
+   u32 head;
enum intel_engine_hangcheck_action action;
unsigned long action_timestamp;
int deadlock;
@@ -134,16 +134,16 @@ static void hangcheck_load_sample(struct intel_engine_cs 
*engine,
  struct hangcheck *hc)
 {
hc->acthd = intel_engine_get_active_head(engine);
-   hc->seqno = intel_engine_get_hangcheck_seqno(engine);
hc->ring = ENGINE_READ(engine, RING_START);
+   hc->head = ENGINE_READ(engine, RING_HEAD);
 }
 
 static void hangcheck_store_sample(struct intel_engine_cs *engine,
   const struct hangcheck *hc)
 {
engine->hangcheck.acthd = hc->acthd;
-   engine->hangcheck.last_seqno = hc->seqno;
engine->hangcheck.last_ring = hc->ring;
+   engine->hangcheck.last_head = hc->head;
 }
 
 static enum intel_engine_hangcheck_action
@@ -156,7 +156,7 @@ hangcheck_get_action(struct intel_engine_cs