diff mbox

[1/5] drm/i915/error: capture execlist state on error

Message ID 1454007684-16777-2-git-send-email-arun.siluvery@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

arun.siluvery@linux.intel.com Jan. 28, 2016, 7:01 p.m. UTC
From: Dave Gordon <david.s.gordon@intel.com>

At present, execlist status/ctx_id and CSBs, not the submission queue

For: VIZ-2021
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |  9 +++++++++
 drivers/gpu/drm/i915/i915_gpu_error.c | 38 +++++++++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 2 deletions(-)

Comments

Mika Kuoppala Jan. 29, 2016, 7:49 a.m. UTC | #1
Arun Siluvery <arun.siluvery@linux.intel.com> writes:

> From: Dave Gordon <david.s.gordon@intel.com>
>
> At present, execlist status/ctx_id and CSBs, not the submission queue
>
> For: VIZ-2021
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |  9 +++++++++
>  drivers/gpu/drm/i915/i915_gpu_error.c | 38 +++++++++++++++++++++++++++++++++--
>  2 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 01cc982..8b30242 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -552,6 +552,15 @@ struct drm_i915_error_state {
>  		u32 rc_psmi; /* sleep state */
>  		u32 semaphore_mboxes[I915_NUM_RINGS - 1];
>  
> +		/* Execlists */
> +		u32 execlist_status;
> +		u32 execlist_ctx_id;
> +		u32 execlist_csb_raw_pointer;
> +		u32 execlist_csb_write_pointer;
> +		u32 execlist_csb_read_pointer;
> +		u32 execlist_csb[6];
> +		u32 execlist_ctx[6];
> +
>  		struct drm_i915_error_object {
>  			int page_count;
>  			u64 gtt_offset;
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 978c026..bf53c2b 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -247,6 +247,7 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
>  				  int ring_idx)
>  {
>  	struct drm_i915_error_ring *ring = &error->ring[ring_idx];
> +	int i;
>  
>  	if (!ring->valid)
>  		return;
> @@ -288,7 +289,6 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
>  		err_printf(m, "  GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode);
>  
>  		if (INTEL_INFO(dev)->gen >= 8) {
> -			int i;
>  			for (i = 0; i < 4; i++)
>  				err_printf(m, "  PDP%d: 0x%016llx\n",
>  					   i, ring->vm_info.pdp[i]);
> @@ -304,6 +304,17 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
>  	err_printf(m, "  hangcheck: %s [%d]\n",
>  		   hangcheck_action_to_str(ring->hangcheck_action),
>  		   ring->hangcheck_score);
> +
> +	err_printf(m, "  EXECLIST_STATUS: 0x%08x\n", ring->execlist_status);
> +	err_printf(m, "  EXECLIST_CTX_ID: 0x%08x\n", ring->execlist_ctx_id);
> +	err_printf(m, "  EXECLIST_CSBPTR: 0x%08x\n", ring->execlist_csb_raw_pointer);
> +	err_printf(m, "  EXECLIST_CSB_WR: 0x%08x\n", ring->execlist_csb_write_pointer);
> +	err_printf(m, "  EXECLIST_CSB_RD: 0x%08x\n", ring->execlist_csb_read_pointer);
> +
> +	for (i = 0; i < 6; i++) {
> +		err_printf(m, "  EXECLIST_CSB[%d]: 0x%08x\n", i, ring->execlist_csb[i]);
> +		err_printf(m, "  EXECLIST_CTX[%d]: 0x%08x\n", i, ring->execlist_ctx[i]);
> +	}

Please output only if i915.enable_execlists.

>  }
>  
>  void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
> @@ -965,8 +976,27 @@ static void i915_record_ring_state(struct drm_device *dev,
>  					I915_READ(GEN8_RING_PDP_LDW(ring, i));
>  			}
>  	}
> -}
>  
> +	if (i915.enable_execlists) {
> +		int i;
> +		u32 status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
> +		u8 write_pointer = status_pointer & 0x07;
> +		u8 read_pointer = ring->next_context_status_buffer;
> +		if (read_pointer > write_pointer)
> +			write_pointer += 6;
> +
> +		ering->execlist_status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
> +		ering->execlist_ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
> +		ering->execlist_csb_raw_pointer = status_pointer;
> +		ering->execlist_csb_write_pointer = write_pointer;
> +		ering->execlist_csb_read_pointer = read_pointer;
> +
> +		for (i = 0; i < 6; i++) {
> +			ering->execlist_csb[i] = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, i));
> +			ering->execlist_ctx[i] = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, i));
> +		}
> +	}
> +}
>  
>  static void i915_gem_record_active_context(struct intel_engine_cs *ring,
>  					   struct drm_i915_error_state *error,
> @@ -1252,6 +1282,10 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
>  	if (HAS_HW_CONTEXTS(dev))
>  		error->ccid = I915_READ(CCID);
>  
> +	if (HAS_LOGICAL_RING_CONTEXTS(dev)) {
> +		// Surely something to capture here ...
> +	}
> +

Nitpick. Dont add empty block for just documentation. 

Thanks,
-Mika


>  	if (INTEL_INFO(dev)->gen >= 8) {
>  		error->ier = I915_READ(GEN8_DE_MISC_IER);
>  		for (i = 0; i < 4; i++)
> -- 
> 1.9.1
Chris Wilson Jan. 29, 2016, 11:45 a.m. UTC | #2
On Fri, Jan 29, 2016 at 09:49:07AM +0200, Mika Kuoppala wrote:
> Arun Siluvery <arun.siluvery@linux.intel.com> writes:
> 
> > From: Dave Gordon <david.s.gordon@intel.com>
> >
> > At present, execlist status/ctx_id and CSBs, not the submission queue
> >
> > For: VIZ-2021
> > Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h       |  9 +++++++++
> >  drivers/gpu/drm/i915/i915_gpu_error.c | 38 +++++++++++++++++++++++++++++++++--
> >  2 files changed, 45 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 01cc982..8b30242 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -552,6 +552,15 @@ struct drm_i915_error_state {
> >  		u32 rc_psmi; /* sleep state */
> >  		u32 semaphore_mboxes[I915_NUM_RINGS - 1];
> >  
> > +		/* Execlists */
> > +		u32 execlist_status;
> > +		u32 execlist_ctx_id;
> > +		u32 execlist_csb_raw_pointer;
> > +		u32 execlist_csb_write_pointer;
> > +		u32 execlist_csb_read_pointer;
> > +		u32 execlist_csb[6];
> > +		u32 execlist_ctx[6];
> > +
> >  		struct drm_i915_error_object {
> >  			int page_count;
> >  			u64 gtt_offset;
> > diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> > index 978c026..bf53c2b 100644
> > --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> > +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> > @@ -247,6 +247,7 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
> >  				  int ring_idx)
> >  {
> >  	struct drm_i915_error_ring *ring = &error->ring[ring_idx];
> > +	int i;
> >  
> >  	if (!ring->valid)
> >  		return;
> > @@ -288,7 +289,6 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
> >  		err_printf(m, "  GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode);
> >  
> >  		if (INTEL_INFO(dev)->gen >= 8) {
> > -			int i;
> >  			for (i = 0; i < 4; i++)
> >  				err_printf(m, "  PDP%d: 0x%016llx\n",
> >  					   i, ring->vm_info.pdp[i]);
> > @@ -304,6 +304,17 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
> >  	err_printf(m, "  hangcheck: %s [%d]\n",
> >  		   hangcheck_action_to_str(ring->hangcheck_action),
> >  		   ring->hangcheck_score);
> > +
> > +	err_printf(m, "  EXECLIST_STATUS: 0x%08x\n", ring->execlist_status);
> > +	err_printf(m, "  EXECLIST_CTX_ID: 0x%08x\n", ring->execlist_ctx_id);
> > +	err_printf(m, "  EXECLIST_CSBPTR: 0x%08x\n", ring->execlist_csb_raw_pointer);
> > +	err_printf(m, "  EXECLIST_CSB_WR: 0x%08x\n", ring->execlist_csb_write_pointer);
> > +	err_printf(m, "  EXECLIST_CSB_RD: 0x%08x\n", ring->execlist_csb_read_pointer);
> > +
> > +	for (i = 0; i < 6; i++) {
> > +		err_printf(m, "  EXECLIST_CSB[%d]: 0x%08x\n", i, ring->execlist_csb[i]);
> > +		err_printf(m, "  EXECLIST_CTX[%d]: 0x%08x\n", i, ring->execlist_ctx[i]);
> > +	}
> 
> Please output only if i915.enable_execlists.
> 
> >  }
> >  
> >  void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
> > @@ -965,8 +976,27 @@ static void i915_record_ring_state(struct drm_device *dev,
> >  					I915_READ(GEN8_RING_PDP_LDW(ring, i));
> >  			}
> >  	}
> > -}
> >  
> > +	if (i915.enable_execlists) {
> > +		int i;
> > +		u32 status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
> > +		u8 write_pointer = status_pointer & 0x07;
> > +		u8 read_pointer = ring->next_context_status_buffer;
> > +		if (read_pointer > write_pointer)
> > +			write_pointer += 6;
> > +
> > +		ering->execlist_status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
> > +		ering->execlist_ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
> > +		ering->execlist_csb_raw_pointer = status_pointer;
> > +		ering->execlist_csb_write_pointer = write_pointer;
> > +		ering->execlist_csb_read_pointer = read_pointer;

Just the registers. How do you plan to use these to debug anything?
-Chris
arun.siluvery@linux.intel.com Jan. 29, 2016, 12:25 p.m. UTC | #3
On 29/01/2016 11:45, Chris Wilson wrote:
> On Fri, Jan 29, 2016 at 09:49:07AM +0200, Mika Kuoppala wrote:
>> Arun Siluvery <arun.siluvery@linux.intel.com> writes:
>>
>>> From: Dave Gordon <david.s.gordon@intel.com>
>>>
>>> At present, execlist status/ctx_id and CSBs, not the submission queue
>>>
>>> For: VIZ-2021
>>> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
>>> ---
>>>   drivers/gpu/drm/i915/i915_drv.h       |  9 +++++++++
>>>   drivers/gpu/drm/i915/i915_gpu_error.c | 38 +++++++++++++++++++++++++++++++++--
>>>   2 files changed, 45 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>>> index 01cc982..8b30242 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -552,6 +552,15 @@ struct drm_i915_error_state {
>>>   		u32 rc_psmi; /* sleep state */
>>>   		u32 semaphore_mboxes[I915_NUM_RINGS - 1];
>>>
>>> +		/* Execlists */
>>> +		u32 execlist_status;
>>> +		u32 execlist_ctx_id;
>>> +		u32 execlist_csb_raw_pointer;
>>> +		u32 execlist_csb_write_pointer;
>>> +		u32 execlist_csb_read_pointer;
>>> +		u32 execlist_csb[6];
>>> +		u32 execlist_ctx[6];
>>> +
>>>   		struct drm_i915_error_object {
>>>   			int page_count;
>>>   			u64 gtt_offset;
>>> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
>>> index 978c026..bf53c2b 100644
>>> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
>>> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
>>> @@ -247,6 +247,7 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
>>>   				  int ring_idx)
>>>   {
>>>   	struct drm_i915_error_ring *ring = &error->ring[ring_idx];
>>> +	int i;
>>>
>>>   	if (!ring->valid)
>>>   		return;
>>> @@ -288,7 +289,6 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
>>>   		err_printf(m, "  GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode);
>>>
>>>   		if (INTEL_INFO(dev)->gen >= 8) {
>>> -			int i;
>>>   			for (i = 0; i < 4; i++)
>>>   				err_printf(m, "  PDP%d: 0x%016llx\n",
>>>   					   i, ring->vm_info.pdp[i]);
>>> @@ -304,6 +304,17 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
>>>   	err_printf(m, "  hangcheck: %s [%d]\n",
>>>   		   hangcheck_action_to_str(ring->hangcheck_action),
>>>   		   ring->hangcheck_score);
>>> +
>>> +	err_printf(m, "  EXECLIST_STATUS: 0x%08x\n", ring->execlist_status);
>>> +	err_printf(m, "  EXECLIST_CTX_ID: 0x%08x\n", ring->execlist_ctx_id);
>>> +	err_printf(m, "  EXECLIST_CSBPTR: 0x%08x\n", ring->execlist_csb_raw_pointer);
>>> +	err_printf(m, "  EXECLIST_CSB_WR: 0x%08x\n", ring->execlist_csb_write_pointer);
>>> +	err_printf(m, "  EXECLIST_CSB_RD: 0x%08x\n", ring->execlist_csb_read_pointer);
>>> +
>>> +	for (i = 0; i < 6; i++) {
>>> +		err_printf(m, "  EXECLIST_CSB[%d]: 0x%08x\n", i, ring->execlist_csb[i]);
>>> +		err_printf(m, "  EXECLIST_CTX[%d]: 0x%08x\n", i, ring->execlist_ctx[i]);
>>> +	}
>>
>> Please output only if i915.enable_execlists.
>>
>>>   }
>>>
>>>   void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
>>> @@ -965,8 +976,27 @@ static void i915_record_ring_state(struct drm_device *dev,
>>>   					I915_READ(GEN8_RING_PDP_LDW(ring, i));
>>>   			}
>>>   	}
>>> -}
>>>
>>> +	if (i915.enable_execlists) {
>>> +		int i;
>>> +		u32 status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
>>> +		u8 write_pointer = status_pointer & 0x07;
>>> +		u8 read_pointer = ring->next_context_status_buffer;
>>> +		if (read_pointer > write_pointer)
>>> +			write_pointer += 6;
>>> +
>>> +		ering->execlist_status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
>>> +		ering->execlist_ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
>>> +		ering->execlist_csb_raw_pointer = status_pointer;
>>> +		ering->execlist_csb_write_pointer = write_pointer;
>>> +		ering->execlist_csb_read_pointer = read_pointer;
>
> Just the registers. How do you plan to use these to debug anything?
csb pointers are helpful when there is an inconsistency between sw and 
hw which can happen if we miss ctx switch interrupts.

regards
Arun

> -Chris
>
Chris Wilson Jan. 29, 2016, 12:38 p.m. UTC | #4
On Fri, Jan 29, 2016 at 12:25:02PM +0000, Arun Siluvery wrote:
> On 29/01/2016 11:45, Chris Wilson wrote:
> >On Fri, Jan 29, 2016 at 09:49:07AM +0200, Mika Kuoppala wrote:
> >>Arun Siluvery <arun.siluvery@linux.intel.com> writes:
> >>
> >>>From: Dave Gordon <david.s.gordon@intel.com>
> >>>
> >>>At present, execlist status/ctx_id and CSBs, not the submission queue
> >>>
> >>>For: VIZ-2021
> >>>Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> >>>---
> >>>  drivers/gpu/drm/i915/i915_drv.h       |  9 +++++++++
> >>>  drivers/gpu/drm/i915/i915_gpu_error.c | 38 +++++++++++++++++++++++++++++++++--
> >>>  2 files changed, 45 insertions(+), 2 deletions(-)
> >>>
> >>>diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> >>>index 01cc982..8b30242 100644
> >>>--- a/drivers/gpu/drm/i915/i915_drv.h
> >>>+++ b/drivers/gpu/drm/i915/i915_drv.h
> >>>@@ -552,6 +552,15 @@ struct drm_i915_error_state {
> >>>  		u32 rc_psmi; /* sleep state */
> >>>  		u32 semaphore_mboxes[I915_NUM_RINGS - 1];
> >>>
> >>>+		/* Execlists */
> >>>+		u32 execlist_status;
> >>>+		u32 execlist_ctx_id;
> >>>+		u32 execlist_csb_raw_pointer;
> >>>+		u32 execlist_csb_write_pointer;
> >>>+		u32 execlist_csb_read_pointer;
> >>>+		u32 execlist_csb[6];
> >>>+		u32 execlist_ctx[6];
> >>>+
> >>>  		struct drm_i915_error_object {
> >>>  			int page_count;
> >>>  			u64 gtt_offset;
> >>>diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> >>>index 978c026..bf53c2b 100644
> >>>--- a/drivers/gpu/drm/i915/i915_gpu_error.c
> >>>+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> >>>@@ -247,6 +247,7 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
> >>>  				  int ring_idx)
> >>>  {
> >>>  	struct drm_i915_error_ring *ring = &error->ring[ring_idx];
> >>>+	int i;
> >>>
> >>>  	if (!ring->valid)
> >>>  		return;
> >>>@@ -288,7 +289,6 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
> >>>  		err_printf(m, "  GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode);
> >>>
> >>>  		if (INTEL_INFO(dev)->gen >= 8) {
> >>>-			int i;
> >>>  			for (i = 0; i < 4; i++)
> >>>  				err_printf(m, "  PDP%d: 0x%016llx\n",
> >>>  					   i, ring->vm_info.pdp[i]);
> >>>@@ -304,6 +304,17 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
> >>>  	err_printf(m, "  hangcheck: %s [%d]\n",
> >>>  		   hangcheck_action_to_str(ring->hangcheck_action),
> >>>  		   ring->hangcheck_score);
> >>>+
> >>>+	err_printf(m, "  EXECLIST_STATUS: 0x%08x\n", ring->execlist_status);
> >>>+	err_printf(m, "  EXECLIST_CTX_ID: 0x%08x\n", ring->execlist_ctx_id);
> >>>+	err_printf(m, "  EXECLIST_CSBPTR: 0x%08x\n", ring->execlist_csb_raw_pointer);
> >>>+	err_printf(m, "  EXECLIST_CSB_WR: 0x%08x\n", ring->execlist_csb_write_pointer);
> >>>+	err_printf(m, "  EXECLIST_CSB_RD: 0x%08x\n", ring->execlist_csb_read_pointer);
> >>>+
> >>>+	for (i = 0; i < 6; i++) {
> >>>+		err_printf(m, "  EXECLIST_CSB[%d]: 0x%08x\n", i, ring->execlist_csb[i]);
> >>>+		err_printf(m, "  EXECLIST_CTX[%d]: 0x%08x\n", i, ring->execlist_ctx[i]);
> >>>+	}
> >>
> >>Please output only if i915.enable_execlists.
> >>
> >>>  }
> >>>
> >>>  void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
> >>>@@ -965,8 +976,27 @@ static void i915_record_ring_state(struct drm_device *dev,
> >>>  					I915_READ(GEN8_RING_PDP_LDW(ring, i));
> >>>  			}
> >>>  	}
> >>>-}
> >>>
> >>>+	if (i915.enable_execlists) {
> >>>+		int i;
> >>>+		u32 status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
> >>>+		u8 write_pointer = status_pointer & 0x07;
> >>>+		u8 read_pointer = ring->next_context_status_buffer;
> >>>+		if (read_pointer > write_pointer)
> >>>+			write_pointer += 6;
> >>>+
> >>>+		ering->execlist_status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
> >>>+		ering->execlist_ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
> >>>+		ering->execlist_csb_raw_pointer = status_pointer;
> >>>+		ering->execlist_csb_write_pointer = write_pointer;
> >>>+		ering->execlist_csb_read_pointer = read_pointer;
> >
> >Just the registers. How do you plan to use these to debug anything?
> csb pointers are helpful when there is an inconsistency between sw
> and hw which can happen if we miss ctx switch interrupts.

Yes, but you are printing them twice. (next_context_status_buffer can be
shot btw)
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 01cc982..8b30242 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -552,6 +552,15 @@  struct drm_i915_error_state {
 		u32 rc_psmi; /* sleep state */
 		u32 semaphore_mboxes[I915_NUM_RINGS - 1];
 
+		/* Execlists */
+		u32 execlist_status;
+		u32 execlist_ctx_id;
+		u32 execlist_csb_raw_pointer;
+		u32 execlist_csb_write_pointer;
+		u32 execlist_csb_read_pointer;
+		u32 execlist_csb[6];
+		u32 execlist_ctx[6];
+
 		struct drm_i915_error_object {
 			int page_count;
 			u64 gtt_offset;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 978c026..bf53c2b 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -247,6 +247,7 @@  static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
 				  int ring_idx)
 {
 	struct drm_i915_error_ring *ring = &error->ring[ring_idx];
+	int i;
 
 	if (!ring->valid)
 		return;
@@ -288,7 +289,6 @@  static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
 		err_printf(m, "  GFX_MODE: 0x%08x\n", ring->vm_info.gfx_mode);
 
 		if (INTEL_INFO(dev)->gen >= 8) {
-			int i;
 			for (i = 0; i < 4; i++)
 				err_printf(m, "  PDP%d: 0x%016llx\n",
 					   i, ring->vm_info.pdp[i]);
@@ -304,6 +304,17 @@  static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
 	err_printf(m, "  hangcheck: %s [%d]\n",
 		   hangcheck_action_to_str(ring->hangcheck_action),
 		   ring->hangcheck_score);
+
+	err_printf(m, "  EXECLIST_STATUS: 0x%08x\n", ring->execlist_status);
+	err_printf(m, "  EXECLIST_CTX_ID: 0x%08x\n", ring->execlist_ctx_id);
+	err_printf(m, "  EXECLIST_CSBPTR: 0x%08x\n", ring->execlist_csb_raw_pointer);
+	err_printf(m, "  EXECLIST_CSB_WR: 0x%08x\n", ring->execlist_csb_write_pointer);
+	err_printf(m, "  EXECLIST_CSB_RD: 0x%08x\n", ring->execlist_csb_read_pointer);
+
+	for (i = 0; i < 6; i++) {
+		err_printf(m, "  EXECLIST_CSB[%d]: 0x%08x\n", i, ring->execlist_csb[i]);
+		err_printf(m, "  EXECLIST_CTX[%d]: 0x%08x\n", i, ring->execlist_ctx[i]);
+	}
 }
 
 void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
@@ -965,8 +976,27 @@  static void i915_record_ring_state(struct drm_device *dev,
 					I915_READ(GEN8_RING_PDP_LDW(ring, i));
 			}
 	}
-}
 
+	if (i915.enable_execlists) {
+		int i;
+		u32 status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
+		u8 write_pointer = status_pointer & 0x07;
+		u8 read_pointer = ring->next_context_status_buffer;
+		if (read_pointer > write_pointer)
+			write_pointer += 6;
+
+		ering->execlist_status = I915_READ(RING_EXECLIST_STATUS_LO(ring));
+		ering->execlist_ctx_id = I915_READ(RING_EXECLIST_STATUS_HI(ring));
+		ering->execlist_csb_raw_pointer = status_pointer;
+		ering->execlist_csb_write_pointer = write_pointer;
+		ering->execlist_csb_read_pointer = read_pointer;
+
+		for (i = 0; i < 6; i++) {
+			ering->execlist_csb[i] = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, i));
+			ering->execlist_ctx[i] = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, i));
+		}
+	}
+}
 
 static void i915_gem_record_active_context(struct intel_engine_cs *ring,
 					   struct drm_i915_error_state *error,
@@ -1252,6 +1282,10 @@  static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
 	if (HAS_HW_CONTEXTS(dev))
 		error->ccid = I915_READ(CCID);
 
+	if (HAS_LOGICAL_RING_CONTEXTS(dev)) {
+		// Surely something to capture here ...
+	}
+
 	if (INTEL_INFO(dev)->gen >= 8) {
 		error->ier = I915_READ(GEN8_DE_MISC_IER);
 		for (i = 0; i < 4; i++)