All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read
@ 2017-04-23 17:06 Chris Wilson
  2017-04-23 17:06 ` [PATCH 2/4] drm/i915: Poison the request before emitting commands Chris Wilson
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-23 17:06 UTC (permalink / raw)
  To: intel-gfx; +Cc: Mika Kuoppala

We need to keep track of the last location we ask the hw to read up to
(RING_TAIL) separately from our last write location into the ring, so
that in the event of a GPU reset we do not tell the HW to proceed into
a partially written request (which can happen if that request is waiting
for an external signal before being executed).

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100144
Testcase: igt/gem_exec_fence/await-hang
Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests")
Fixes: d55ac5bf97c6 ("drm/i915: Defer transfer onto execution timeline to actual hw submission")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c    |  2 +-
 drivers/gpu/drm/i915/i915_guc_submission.c |  4 +--
 drivers/gpu/drm/i915/intel_lrc.c           |  6 ++---
 drivers/gpu/drm/i915/intel_ringbuffer.c    | 42 +++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_ringbuffer.h    | 17 +++++++++++-
 5 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index e2ec42b2bf24..99146de1dc93 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -651,7 +651,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
 	 * GPU processing the request, we never over-estimate the
 	 * position of the head.
 	 */
-	req->head = req->ring->tail;
+	req->head = req->ring->emit;
 
 	/* Check that we didn't interrupt ourselves with a new request */
 	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 1642fff9cf13..ab5140ba108d 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -480,9 +480,7 @@ static void guc_wq_item_append(struct i915_guc_client *client,
 	GEM_BUG_ON(freespace < wqi_size);
 
 	/* The GuC firmware wants the tail index in QWords, not bytes */
-	tail = rq->tail;
-	assert_ring_tail_valid(rq->ring, rq->tail);
-	tail >>= 3;
+	tail = intel_ring_set_tail(rq->ring, rq->tail) >> 3;
 	GEM_BUG_ON(tail > WQ_RING_TAIL_MAX);
 
 	/* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 7df278fe492e..d3612969098f 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -326,8 +326,7 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq)
 		rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
 	u32 *reg_state = ce->lrc_reg_state;
 
-	assert_ring_tail_valid(rq->ring, rq->tail);
-	reg_state[CTX_RING_TAIL+1] = rq->tail;
+	reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
 
 	/* True 32b PPGTT with dynamic page allocation: update PDP
 	 * registers and point the unallocated PDPs to scratch page.
@@ -2054,7 +2053,8 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
 			ce->state->obj->mm.dirty = true;
 			i915_gem_object_unpin_map(ce->state->obj);
 
-			ce->ring->head = ce->ring->tail = 0;
+			GEM_BUG_ON(!list_empty(&ce->ring->request_list));
+			ce->ring->head = ce->ring->tail = ce->ring->emit = 0;
 			intel_ring_update_space(ce->ring);
 		}
 	}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 32afac6c754f..8c874996c617 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -49,7 +49,7 @@ static int __intel_ring_space(int head, int tail, int size)
 
 void intel_ring_update_space(struct intel_ring *ring)
 {
-	ring->space = __intel_ring_space(ring->head, ring->tail, ring->size);
+	ring->space = __intel_ring_space(ring->head, ring->emit, ring->size);
 }
 
 static int
@@ -774,8 +774,8 @@ static void i9xx_submit_request(struct drm_i915_gem_request *request)
 
 	i915_gem_request_submit(request);
 
-	assert_ring_tail_valid(request->ring, request->tail);
-	I915_WRITE_TAIL(request->engine, request->tail);
+	I915_WRITE_TAIL(request->engine,
+			intel_ring_set_tail(request->ring, request->tail));
 }
 
 static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
@@ -1324,6 +1324,12 @@ void intel_ring_unpin(struct intel_ring *ring)
 	GEM_BUG_ON(!ring->vma);
 	GEM_BUG_ON(!ring->vaddr);
 
+	/* Discard any unused bytes beyond that submitted to hw. */
+	GEM_BUG_ON(!list_empty(&ring->request_list));
+	ring->head = ring->tail;
+	ring->emit = ring->tail;
+	intel_ring_update_space(ring);
+
 	if (i915_vma_is_map_and_fenceable(ring->vma))
 		i915_vma_unpin_iomap(ring->vma);
 	else
@@ -1555,8 +1561,14 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv)
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 
-	for_each_engine(engine, dev_priv, id)
-		engine->buffer->head = engine->buffer->tail;
+	/* Restart from the beginning of the rings for convenience */
+	for_each_engine(engine, dev_priv, id) {
+		struct intel_ring *ring = engine->buffer;
+
+		GEM_BUG_ON(!list_empty(&ring->request_list));
+		ring->head = ring->tail = ring->emit = 0;
+		intel_ring_update_space(ring);
+	}
 }
 
 static int ring_request_alloc(struct drm_i915_gem_request *request)
@@ -1609,7 +1621,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 		unsigned space;
 
 		/* Would completion of this request free enough space? */
-		space = __intel_ring_space(target->postfix, ring->tail,
+		space = __intel_ring_space(target->postfix, ring->emit,
 					   ring->size);
 		if (space >= bytes)
 			break;
@@ -1634,8 +1646,8 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 {
 	struct intel_ring *ring = req->ring;
-	int remain_actual = ring->size - ring->tail;
-	int remain_usable = ring->effective_size - ring->tail;
+	int remain_actual = ring->size - ring->emit;
+	int remain_usable = ring->effective_size - ring->emit;
 	int bytes = num_dwords * sizeof(u32);
 	int total_bytes, wait_bytes;
 	bool need_wrap = false;
@@ -1671,17 +1683,17 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 
 	if (unlikely(need_wrap)) {
 		GEM_BUG_ON(remain_actual > ring->space);
-		GEM_BUG_ON(ring->tail + remain_actual > ring->size);
+		GEM_BUG_ON(ring->emit + remain_actual > ring->size);
 
 		/* Fill the tail with MI_NOOP */
-		memset(ring->vaddr + ring->tail, 0, remain_actual);
-		ring->tail = 0;
+		memset(ring->vaddr + ring->emit, 0, remain_actual);
+		ring->emit = 0;
 		ring->space -= remain_actual;
 	}
 
-	GEM_BUG_ON(ring->tail > ring->size - bytes);
-	cs = ring->vaddr + ring->tail;
-	ring->tail += bytes;
+	GEM_BUG_ON(ring->emit > ring->size - bytes);
+	cs = ring->vaddr + ring->emit;
+	ring->emit += bytes;
 	ring->space -= bytes;
 	GEM_BUG_ON(ring->space < 0);
 
@@ -1692,7 +1704,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 int intel_ring_cacheline_align(struct drm_i915_gem_request *req)
 {
 	int num_dwords =
-		(req->ring->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
+		(req->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
 	u32 *cs;
 
 	if (num_dwords == 0)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 00d36aa4e26d..31998ea46fb8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -143,6 +143,7 @@ struct intel_ring {
 
 	u32 head;
 	u32 tail;
+	u32 emit;
 
 	int space;
 	int size;
@@ -517,7 +518,7 @@ intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs)
 	 * reserved for the command packet (i.e. the value passed to
 	 * intel_ring_begin()).
 	 */
-	GEM_BUG_ON((req->ring->vaddr + req->ring->tail) != cs);
+	GEM_BUG_ON((req->ring->vaddr + req->ring->emit) != cs);
 }
 
 static inline u32
@@ -546,6 +547,20 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
 	GEM_BUG_ON(tail >= ring->size);
 }
 
+static inline unsigned int
+intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
+{
+	/* Whilst writes to the tail are strictly order, there is no
+	 * serialisation between readers and the writers. The tail may be
+	 * read by i915_gem_request_retire() just as it is being updated
+	 * by execlists, as although the breadcrumb is complete, the context
+	 * switch hasn't been seen.
+	 */
+	assert_ring_tail_valid(ring, tail);
+	ring->tail = tail;
+	return tail;
+}
+
 void intel_ring_update_space(struct intel_ring *ring);
 
 void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/4] drm/i915: Poison the request before emitting commands
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
@ 2017-04-23 17:06 ` Chris Wilson
  2017-04-24 12:29   ` Mika Kuoppala
  2017-04-23 17:06 ` [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically Chris Wilson
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-23 17:06 UTC (permalink / raw)
  To: intel-gfx

If we poison the request before we emit commands, it should be easier to
spot when we execute an uninitialised request.

References: https://bugs.freedesktop.org/show_bug.cgi?id=100144
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 8c874996c617..1ec98851a621 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1693,6 +1693,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 
 	GEM_BUG_ON(ring->emit > ring->size - bytes);
 	cs = ring->vaddr + ring->emit;
+	GEM_DEBUG_EXEC(memset(cs, POISON_INUSE, bytes));
 	ring->emit += bytes;
 	ring->space -= bytes;
 	GEM_BUG_ON(ring->space < 0);
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
  2017-04-23 17:06 ` [PATCH 2/4] drm/i915: Poison the request before emitting commands Chris Wilson
@ 2017-04-23 17:06 ` Chris Wilson
  2017-04-24 12:37   ` Mika Kuoppala
  2017-04-23 17:06 ` [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug Chris Wilson
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-23 17:06 UTC (permalink / raw)
  To: intel-gfx

We only have to prevent the RING_TAIL from catching the RING_HEAD
cacheline and do not need to enforce a whole cacheline separation, and in
the process we can remove one branch from the computation.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 20 ++++++++++----------
 drivers/gpu/drm/i915/intel_ringbuffer.h | 24 +++++++++++++-----------
 2 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1ec98851a621..48d4b5b24b21 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -39,12 +39,15 @@
  */
 #define LEGACY_REQUEST_SIZE 200
 
-static int __intel_ring_space(int head, int tail, int size)
+static unsigned int __intel_ring_space(unsigned int head,
+				       unsigned int tail,
+				       unsigned int size)
 {
-	int space = head - tail;
-	if (space <= 0)
-		space += size;
-	return space - I915_RING_FREE_SPACE;
+	/* "If the Ring Buffer Head Pointer and the Tail Pointer are on the
+	 * same cacheline, the Head Pointer must not be greater than the Tail
+	 * Pointer."
+	 */
+	return (round_down(head, CACHELINE_BYTES) - tail - 8) & (size - 1);
 }
 
 void intel_ring_update_space(struct intel_ring *ring)
@@ -1618,12 +1621,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 	GEM_BUG_ON(!req->reserved_space);
 
 	list_for_each_entry(target, &ring->request_list, ring_link) {
-		unsigned space;
-
 		/* Would completion of this request free enough space? */
-		space = __intel_ring_space(target->postfix, ring->emit,
-					   ring->size);
-		if (space >= bytes)
+		if (bytes <= __intel_ring_space(target->postfix,
+						ring->emit, ring->size))
 			break;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 31998ea46fb8..e28ffc98c520 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -17,17 +17,6 @@
 #define CACHELINE_BYTES 64
 #define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(uint32_t))
 
-/*
- * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use"
- * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use"
- * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use"
- *
- * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same
- * cacheline, the Head Pointer must not be greater than the Tail
- * Pointer."
- */
-#define I915_RING_FREE_SPACE 64
-
 struct intel_hw_status_page {
 	struct i915_vma *vma;
 	u32 *page_addr;
@@ -545,6 +534,19 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
 	 */
 	GEM_BUG_ON(!IS_ALIGNED(tail, 8));
 	GEM_BUG_ON(tail >= ring->size);
+
+	/* "Ring Buffer Use"
+	 *	Gen2 BSpec "1. Programming Environment" / 1.4.4.6
+	 *	Gen3 BSpec "1c Memory Interface Functions" / 2.3.4.5
+	 *	Gen4+ BSpec "1c Memory Interface and Command Stream" / 5.3.4.5
+	 * "If the Ring Buffer Head Pointer and the Tail Pointer are on the
+	 * same cacheline, the Head Pointer must not be greater than the Tail
+	 * Pointer."
+	 */
+#define cacheline(a) round_down(a, CACHELINE_BYTES)
+	GEM_BUG_ON(cacheline(tail) == cacheline(ring->head) &&
+		   tail < ring->head);
+#undef cacheline
 }
 
 static inline unsigned int
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
  2017-04-23 17:06 ` [PATCH 2/4] drm/i915: Poison the request before emitting commands Chris Wilson
  2017-04-23 17:06 ` [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically Chris Wilson
@ 2017-04-23 17:06 ` Chris Wilson
  2017-04-24 12:52   ` Mika Kuoppala
  2017-04-23 17:24 ` ✓ Fi.CI.BAT: success for series starting with [1/4] drm/i915: Differentiate between sw write location into ring and last hw read Patchwork
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-23 17:06 UTC (permalink / raw)
  To: intel-gfx

Knowing the neighbouring seqno (current on hw, last submitted to hw)
provide some useful breadcrumbs to the debug log.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_breadcrumbs.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 9ccbf26124c6..35da5928bd8a 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -64,10 +64,12 @@ static unsigned long wait_timeout(void)
 
 static noinline void missed_breadcrumb(struct intel_engine_cs *engine)
 {
-	DRM_DEBUG_DRIVER("%s missed breadcrumb at %pF, irq posted? %s\n",
+	DRM_DEBUG_DRIVER("%s missed breadcrumb at %pF, irq posted? %s, current seqno=%x, last=%x\n",
 			 engine->name, __builtin_return_address(0),
 			 yesno(test_bit(ENGINE_IRQ_BREADCRUMB,
-					&engine->irq_posted)));
+					&engine->irq_posted)),
+			 intel_engine_get_seqno(engine),
+			 intel_engine_last_submit(engine));
 
 	set_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
 }
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* ✓ Fi.CI.BAT: success for series starting with [1/4] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
                   ` (2 preceding siblings ...)
  2017-04-23 17:06 ` [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug Chris Wilson
@ 2017-04-23 17:24 ` Patchwork
  2017-04-23 17:52 ` [PATCH 1/4] " Chris Wilson
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2017-04-23 17:24 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/4] drm/i915: Differentiate between sw write location into ring and last hw read
URL   : https://patchwork.freedesktop.org/series/23411/
State : success

== Summary ==

Series 23411v1 Series without cover letter
https://patchwork.freedesktop.org/api/1.0/series/23411/revisions/1/mbox/

Test gem_exec_flush:
        Subgroup basic-batch-kernel-default-uc:
                fail       -> PASS       (fi-snb-2600) fdo#100007

fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007

fi-bdw-5557u     total:278  pass:267  dwarn:0   dfail:0   fail:0   skip:11  time:429s
fi-bdw-gvtdvm    total:278  pass:256  dwarn:8   dfail:0   fail:0   skip:14  time:427s
fi-bsw-n3050     total:278  pass:242  dwarn:0   dfail:0   fail:0   skip:36  time:568s
fi-byt-j1900     total:278  pass:254  dwarn:0   dfail:0   fail:0   skip:24  time:488s
fi-byt-n2820     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:480s
fi-hsw-4770      total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:407s
fi-hsw-4770r     total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:408s
fi-ilk-650       total:278  pass:228  dwarn:0   dfail:0   fail:0   skip:50  time:421s
fi-ivb-3520m     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:486s
fi-ivb-3770      total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:460s
fi-skl-6700hq    total:278  pass:261  dwarn:0   dfail:0   fail:0   skip:17  time:571s
fi-skl-6700k     total:278  pass:256  dwarn:4   dfail:0   fail:0   skip:18  time:459s
fi-skl-gvtdvm    total:278  pass:265  dwarn:0   dfail:0   fail:0   skip:13  time:433s
fi-snb-2520m     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:532s
fi-snb-2600      total:278  pass:249  dwarn:0   dfail:0   fail:0   skip:29  time:398s

bc781a3cf9a80e4c5ed0d47fd0c67923bcfcdf2c drm-tip: 2017y-04m-22d-08h-49m-55s UTC integration manifest
f2ea86b drm/i915: Include interesting seqno in the missed breadcrumb debug
ae97cd3 drm/i915: Compute the ring->space slightly less pessimistically
3029d6d drm/i915: Poison the request before emitting commands
9b81660 drm/i915: Differentiate between sw write location into ring and last hw read

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_4533/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
                   ` (3 preceding siblings ...)
  2017-04-23 17:24 ` ✓ Fi.CI.BAT: success for series starting with [1/4] drm/i915: Differentiate between sw write location into ring and last hw read Patchwork
@ 2017-04-23 17:52 ` Chris Wilson
  2017-04-24 12:21 ` Mika Kuoppala
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-23 17:52 UTC (permalink / raw)
  To: intel-gfx; +Cc: Mika Kuoppala

On Sun, Apr 23, 2017 at 06:06:16PM +0100, Chris Wilson wrote:
> +static inline unsigned int
> +intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
> +{
> +	/* Whilst writes to the tail are strictly order, there is no
> +	 * serialisation between readers and the writers. The tail may be
> +	 * read by i915_gem_request_retire() just as it is being updated
> +	 * by execlists, as although the breadcrumb is complete, the context
> +	 * switch hasn't been seen.
> +	 */
> +	assert_ring_tail_valid(ring, tail);
> +	ring->tail = tail;

Could reinforce this with WRITE_ONCE(ring->tail, tail);
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
                   ` (4 preceding siblings ...)
  2017-04-23 17:52 ` [PATCH 1/4] " Chris Wilson
@ 2017-04-24 12:21 ` Mika Kuoppala
  2017-04-24 12:32   ` Chris Wilson
  2017-04-25 13:00 ` [PATCH v2] " Chris Wilson
  2017-04-25 13:19 ` ✓ Fi.CI.BAT: success for series starting with [v2] drm/i915: Differentiate between sw write location into ring and last hw read (rev2) Patchwork
  7 siblings, 1 reply; 19+ messages in thread
From: Mika Kuoppala @ 2017-04-24 12:21 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> We need to keep track of the last location we ask the hw to read up to
> (RING_TAIL) separately from our last write location into the ring, so
> that in the event of a GPU reset we do not tell the HW to proceed into
> a partially written request (which can happen if that request is waiting
> for an external signal before being executed).

But is it so that this can happen also without external signal?
Our submit is already async and waiting for the prev. And we have
already pushed the tail into the partial 'current'.

-Mika

>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100144
> Testcase: igt/gem_exec_fence/await-hang
> Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests")
> Fixes: d55ac5bf97c6 ("drm/i915: Defer transfer onto execution timeline to actual hw submission")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_request.c    |  2 +-
>  drivers/gpu/drm/i915/i915_guc_submission.c |  4 +--
>  drivers/gpu/drm/i915/intel_lrc.c           |  6 ++---
>  drivers/gpu/drm/i915/intel_ringbuffer.c    | 42 +++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_ringbuffer.h    | 17 +++++++++++-
>  5 files changed, 48 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index e2ec42b2bf24..99146de1dc93 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -651,7 +651,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>  	 * GPU processing the request, we never over-estimate the
>  	 * position of the head.
>  	 */
> -	req->head = req->ring->tail;
> +	req->head = req->ring->emit;
>  
>  	/* Check that we didn't interrupt ourselves with a new request */
>  	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 1642fff9cf13..ab5140ba108d 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -480,9 +480,7 @@ static void guc_wq_item_append(struct i915_guc_client *client,
>  	GEM_BUG_ON(freespace < wqi_size);
>  
>  	/* The GuC firmware wants the tail index in QWords, not bytes */
> -	tail = rq->tail;
> -	assert_ring_tail_valid(rq->ring, rq->tail);
> -	tail >>= 3;
> +	tail = intel_ring_set_tail(rq->ring, rq->tail) >> 3;
>  	GEM_BUG_ON(tail > WQ_RING_TAIL_MAX);
>  
>  	/* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 7df278fe492e..d3612969098f 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -326,8 +326,7 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq)
>  		rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
>  	u32 *reg_state = ce->lrc_reg_state;
>  
> -	assert_ring_tail_valid(rq->ring, rq->tail);
> -	reg_state[CTX_RING_TAIL+1] = rq->tail;
> +	reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
>  
>  	/* True 32b PPGTT with dynamic page allocation: update PDP
>  	 * registers and point the unallocated PDPs to scratch page.
> @@ -2054,7 +2053,8 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
>  			ce->state->obj->mm.dirty = true;
>  			i915_gem_object_unpin_map(ce->state->obj);
>  
> -			ce->ring->head = ce->ring->tail = 0;
> +			GEM_BUG_ON(!list_empty(&ce->ring->request_list));
> +			ce->ring->head = ce->ring->tail = ce->ring->emit = 0;
>  			intel_ring_update_space(ce->ring);
>  		}
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 32afac6c754f..8c874996c617 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -49,7 +49,7 @@ static int __intel_ring_space(int head, int tail, int size)
>  
>  void intel_ring_update_space(struct intel_ring *ring)
>  {
> -	ring->space = __intel_ring_space(ring->head, ring->tail, ring->size);
> +	ring->space = __intel_ring_space(ring->head, ring->emit, ring->size);
>  }
>  
>  static int
> @@ -774,8 +774,8 @@ static void i9xx_submit_request(struct drm_i915_gem_request *request)
>  
>  	i915_gem_request_submit(request);
>  
> -	assert_ring_tail_valid(request->ring, request->tail);
> -	I915_WRITE_TAIL(request->engine, request->tail);
> +	I915_WRITE_TAIL(request->engine,
> +			intel_ring_set_tail(request->ring, request->tail));
>  }
>  
>  static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
> @@ -1324,6 +1324,12 @@ void intel_ring_unpin(struct intel_ring *ring)
>  	GEM_BUG_ON(!ring->vma);
>  	GEM_BUG_ON(!ring->vaddr);
>  
> +	/* Discard any unused bytes beyond that submitted to hw. */
> +	GEM_BUG_ON(!list_empty(&ring->request_list));
> +	ring->head = ring->tail;
> +	ring->emit = ring->tail;
> +	intel_ring_update_space(ring);
> +
>  	if (i915_vma_is_map_and_fenceable(ring->vma))
>  		i915_vma_unpin_iomap(ring->vma);
>  	else
> @@ -1555,8 +1561,14 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv)
>  	struct intel_engine_cs *engine;
>  	enum intel_engine_id id;
>  
> -	for_each_engine(engine, dev_priv, id)
> -		engine->buffer->head = engine->buffer->tail;
> +	/* Restart from the beginning of the rings for convenience */
> +	for_each_engine(engine, dev_priv, id) {
> +		struct intel_ring *ring = engine->buffer;
> +
> +		GEM_BUG_ON(!list_empty(&ring->request_list));
> +		ring->head = ring->tail = ring->emit = 0;
> +		intel_ring_update_space(ring);
> +	}
>  }
>  
>  static int ring_request_alloc(struct drm_i915_gem_request *request)
> @@ -1609,7 +1621,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
>  		unsigned space;
>  
>  		/* Would completion of this request free enough space? */
> -		space = __intel_ring_space(target->postfix, ring->tail,
> +		space = __intel_ring_space(target->postfix, ring->emit,
>  					   ring->size);
>  		if (space >= bytes)
>  			break;
> @@ -1634,8 +1646,8 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
>  u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  {
>  	struct intel_ring *ring = req->ring;
> -	int remain_actual = ring->size - ring->tail;
> -	int remain_usable = ring->effective_size - ring->tail;
> +	int remain_actual = ring->size - ring->emit;
> +	int remain_usable = ring->effective_size - ring->emit;
>  	int bytes = num_dwords * sizeof(u32);
>  	int total_bytes, wait_bytes;
>  	bool need_wrap = false;
> @@ -1671,17 +1683,17 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  
>  	if (unlikely(need_wrap)) {
>  		GEM_BUG_ON(remain_actual > ring->space);
> -		GEM_BUG_ON(ring->tail + remain_actual > ring->size);
> +		GEM_BUG_ON(ring->emit + remain_actual > ring->size);
>  
>  		/* Fill the tail with MI_NOOP */
> -		memset(ring->vaddr + ring->tail, 0, remain_actual);
> -		ring->tail = 0;
> +		memset(ring->vaddr + ring->emit, 0, remain_actual);
> +		ring->emit = 0;
>  		ring->space -= remain_actual;
>  	}
>  
> -	GEM_BUG_ON(ring->tail > ring->size - bytes);
> -	cs = ring->vaddr + ring->tail;
> -	ring->tail += bytes;
> +	GEM_BUG_ON(ring->emit > ring->size - bytes);
> +	cs = ring->vaddr + ring->emit;
> +	ring->emit += bytes;
>  	ring->space -= bytes;
>  	GEM_BUG_ON(ring->space < 0);
>  
> @@ -1692,7 +1704,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  int intel_ring_cacheline_align(struct drm_i915_gem_request *req)
>  {
>  	int num_dwords =
> -		(req->ring->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
> +		(req->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
>  	u32 *cs;
>  
>  	if (num_dwords == 0)
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 00d36aa4e26d..31998ea46fb8 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -143,6 +143,7 @@ struct intel_ring {
>  
>  	u32 head;
>  	u32 tail;
> +	u32 emit;
>  
>  	int space;
>  	int size;
> @@ -517,7 +518,7 @@ intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs)
>  	 * reserved for the command packet (i.e. the value passed to
>  	 * intel_ring_begin()).
>  	 */
> -	GEM_BUG_ON((req->ring->vaddr + req->ring->tail) != cs);
> +	GEM_BUG_ON((req->ring->vaddr + req->ring->emit) != cs);
>  }
>  
>  static inline u32
> @@ -546,6 +547,20 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
>  	GEM_BUG_ON(tail >= ring->size);
>  }
>  
> +static inline unsigned int
> +intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
> +{
> +	/* Whilst writes to the tail are strictly order, there is no
> +	 * serialisation between readers and the writers. The tail may be
> +	 * read by i915_gem_request_retire() just as it is being updated
> +	 * by execlists, as although the breadcrumb is complete, the context
> +	 * switch hasn't been seen.
> +	 */
> +	assert_ring_tail_valid(ring, tail);
> +	ring->tail = tail;
> +	return tail;
> +}
> +
>  void intel_ring_update_space(struct intel_ring *ring);
>  
>  void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);
> -- 
> 2.11.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/4] drm/i915: Poison the request before emitting commands
  2017-04-23 17:06 ` [PATCH 2/4] drm/i915: Poison the request before emitting commands Chris Wilson
@ 2017-04-24 12:29   ` Mika Kuoppala
  2017-04-24 12:50     ` Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Mika Kuoppala @ 2017-04-24 12:29 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> If we poison the request before we emit commands, it should be easier to
> spot when we execute an uninitialised request.
>
> References: https://bugs.freedesktop.org/show_bug.cgi?id=100144
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/intel_ringbuffer.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 8c874996c617..1ec98851a621 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -1693,6 +1693,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  
>  	GEM_BUG_ON(ring->emit > ring->size - bytes);
>  	cs = ring->vaddr + ring->emit;
> +	GEM_DEBUG_EXEC(memset(cs, POISON_INUSE, bytes));

Will more modern hardware just skipover these? If so
then perhaps more advanced solution would be to fill with bb
start into the previous address to get a guaranteed
hang on the spot.

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

>  	ring->emit += bytes;
>  	ring->space -= bytes;
>  	GEM_BUG_ON(ring->space < 0);
> -- 
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-24 12:21 ` Mika Kuoppala
@ 2017-04-24 12:32   ` Chris Wilson
  2017-04-24 12:41     ` Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-24 12:32 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On Mon, Apr 24, 2017 at 03:21:56PM +0300, Mika Kuoppala wrote:
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > We need to keep track of the last location we ask the hw to read up to
> > (RING_TAIL) separately from our last write location into the ring, so
> > that in the event of a GPU reset we do not tell the HW to proceed into
> > a partially written request (which can happen if that request is waiting
> > for an external signal before being executed).
> 
> But is it so that this can happen also without external signal?
> Our submit is already async and waiting for the prev. And we have
> already pushed the tail into the partial 'current'.

You need something to delay the request submission. In gem_exec_fence,
it is waiting on a request from another engine (that happens to be a
deliberate hang). Similarly, any third party signal would leave the
request incomplete whilst we continue to write new requests after it.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically
  2017-04-23 17:06 ` [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically Chris Wilson
@ 2017-04-24 12:37   ` Mika Kuoppala
  2017-04-24 12:52     ` Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Mika Kuoppala @ 2017-04-24 12:37 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> We only have to prevent the RING_TAIL from catching the RING_HEAD
> cacheline and do not need to enforce a whole cacheline separation, and in
> the process we can remove one branch from the computation.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/intel_ringbuffer.c | 20 ++++++++++----------
>  drivers/gpu/drm/i915/intel_ringbuffer.h | 24 +++++++++++++-----------
>  2 files changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 1ec98851a621..48d4b5b24b21 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -39,12 +39,15 @@
>   */
>  #define LEGACY_REQUEST_SIZE 200
>  
> -static int __intel_ring_space(int head, int tail, int size)
> +static unsigned int __intel_ring_space(unsigned int head,
> +				       unsigned int tail,
> +				       unsigned int size)
>  {
> -	int space = head - tail;
> -	if (space <= 0)
> -		space += size;
> -	return space - I915_RING_FREE_SPACE;
> +	/* "If the Ring Buffer Head Pointer and the Tail Pointer are on the
> +	 * same cacheline, the Head Pointer must not be greater than the Tail
> +	 * Pointer."
> +	 */
> +	return (round_down(head, CACHELINE_BYTES) - tail - 8) & (size - 1);
>  }
>  
>  void intel_ring_update_space(struct intel_ring *ring)
> @@ -1618,12 +1621,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
>  	GEM_BUG_ON(!req->reserved_space);
>  
>  	list_for_each_entry(target, &ring->request_list, ring_link) {
> -		unsigned space;
> -
>  		/* Would completion of this request free enough space? */
> -		space = __intel_ring_space(target->postfix, ring->emit,
> -					   ring->size);
> -		if (space >= bytes)
> +		if (bytes <= __intel_ring_space(target->postfix,
> +						ring->emit, ring->size))
>  			break;
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 31998ea46fb8..e28ffc98c520 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -17,17 +17,6 @@
>  #define CACHELINE_BYTES 64
>  #define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(uint32_t))
>  
> -/*
> - * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use"
> - * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use"
> - * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use"
> - *
> - * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same
> - * cacheline, the Head Pointer must not be greater than the Tail
> - * Pointer."
> - */
> -#define I915_RING_FREE_SPACE 64
> -
>  struct intel_hw_status_page {
>  	struct i915_vma *vma;
>  	u32 *page_addr;
> @@ -545,6 +534,19 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
>  	 */
>  	GEM_BUG_ON(!IS_ALIGNED(tail, 8));
>  	GEM_BUG_ON(tail >= ring->size);
> +
> +	/* "Ring Buffer Use"
> +	 *	Gen2 BSpec "1. Programming Environment" / 1.4.4.6
> +	 *	Gen3 BSpec "1c Memory Interface Functions" / 2.3.4.5
> +	 *	Gen4+ BSpec "1c Memory Interface and Command Stream" / 5.3.4.5
> +	 * "If the Ring Buffer Head Pointer and the Tail Pointer are on the
> +	 * same cacheline, the Head Pointer must not be greater than the Tail
> +	 * Pointer."
> +	 */
> +#define cacheline(a) round_down(a, CACHELINE_BYTES)
> +	GEM_BUG_ON(cacheline(tail) == cacheline(ring->head) &&

We are about to set the hw tail. But we are using our
outdated bookkeepping value of ring head to do the check.

I am confused. Is this something that can happen only when
it wraps. And why we dont need to check the HW head?

-Mika


> +		   tail < ring->head);
> +#undef cacheline
>  }
>  
>  static inline unsigned int
> -- 
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-24 12:32   ` Chris Wilson
@ 2017-04-24 12:41     ` Chris Wilson
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-24 12:41 UTC (permalink / raw)
  To: Mika Kuoppala, intel-gfx, Tvrtko Ursulin

On Mon, Apr 24, 2017 at 01:32:03PM +0100, Chris Wilson wrote:
> On Mon, Apr 24, 2017 at 03:21:56PM +0300, Mika Kuoppala wrote:
> > Chris Wilson <chris@chris-wilson.co.uk> writes:
> > 
> > > We need to keep track of the last location we ask the hw to read up to
> > > (RING_TAIL) separately from our last write location into the ring, so
> > > that in the event of a GPU reset we do not tell the HW to proceed into
> > > a partially written request (which can happen if that request is waiting
> > > for an external signal before being executed).
> > 
> > But is it so that this can happen also without external signal?
> > Our submit is already async and waiting for the prev. And we have
> > already pushed the tail into the partial 'current'.
> 
> You need something to delay the request submission. In gem_exec_fence,
> it is waiting on a request from another engine (that happens to be a
> deliberate hang). Similarly, any third party signal would leave the
> request incomplete whilst we continue to write new requests after it.

To remind myself, the culprit was the I915_WRITE_TAIL(ring->tail) in
engine->reset_hw() that didn't just restore the previous I915_WRITE_TAIL
from the last submit_request, but would advance into the partials.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/4] drm/i915: Poison the request before emitting commands
  2017-04-24 12:29   ` Mika Kuoppala
@ 2017-04-24 12:50     ` Chris Wilson
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-24 12:50 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On Mon, Apr 24, 2017 at 03:29:48PM +0300, Mika Kuoppala wrote:
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > If we poison the request before we emit commands, it should be easier to
> > spot when we execute an uninitialised request.
> >
> > References: https://bugs.freedesktop.org/show_bug.cgi?id=100144
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> >  drivers/gpu/drm/i915/intel_ringbuffer.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > index 8c874996c617..1ec98851a621 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > @@ -1693,6 +1693,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
> >  
> >  	GEM_BUG_ON(ring->emit > ring->size - bytes);
> >  	cs = ring->vaddr + ring->emit;
> > +	GEM_DEBUG_EXEC(memset(cs, POISON_INUSE, bytes));
> 
> Will more modern hardware just skipover these? If so
> then perhaps more advanced solution would be to fill with bb
> start into the previous address to get a guaranteed
> hang on the spot.

It's not so much the expectation that the value will cause a hang, but
that the value is much more recognisable when diagnosing after something
goes wrong. Such as we do write a complete LRI but forget the value, the
command is correct and so no harm caused, but we may spot the poison
later on.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug
  2017-04-23 17:06 ` [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug Chris Wilson
@ 2017-04-24 12:52   ` Mika Kuoppala
  2017-04-24 14:56     ` Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Mika Kuoppala @ 2017-04-24 12:52 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> Knowing the neighbouring seqno (current on hw, last submitted to hw)
> provide some useful breadcrumbs to the debug log.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_breadcrumbs.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> index 9ccbf26124c6..35da5928bd8a 100644
> --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> @@ -64,10 +64,12 @@ static unsigned long wait_timeout(void)
>  
>  static noinline void missed_breadcrumb(struct intel_engine_cs *engine)
>  {
> -	DRM_DEBUG_DRIVER("%s missed breadcrumb at %pF, irq posted? %s\n",
> +	DRM_DEBUG_DRIVER("%s missed breadcrumb at %pF, irq posted? %s, current seqno=%x, last=%x\n",
>  			 engine->name, __builtin_return_address(0),
>  			 yesno(test_bit(ENGINE_IRQ_BREADCRUMB,
> -					&engine->irq_posted)));
> +					&engine->irq_posted)),
> +			 intel_engine_get_seqno(engine),
> +			 intel_engine_last_submit(engine));
>  
>  	set_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
>  }
> -- 
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically
  2017-04-24 12:37   ` Mika Kuoppala
@ 2017-04-24 12:52     ` Chris Wilson
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-24 12:52 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On Mon, Apr 24, 2017 at 03:37:44PM +0300, Mika Kuoppala wrote:
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > We only have to prevent the RING_TAIL from catching the RING_HEAD
> > cacheline and do not need to enforce a whole cacheline separation, and in
> > the process we can remove one branch from the computation.
> >
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> >  drivers/gpu/drm/i915/intel_ringbuffer.c | 20 ++++++++++----------
> >  drivers/gpu/drm/i915/intel_ringbuffer.h | 24 +++++++++++++-----------
> >  2 files changed, 23 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > index 1ec98851a621..48d4b5b24b21 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> > @@ -39,12 +39,15 @@
> >   */
> >  #define LEGACY_REQUEST_SIZE 200
> >  
> > -static int __intel_ring_space(int head, int tail, int size)
> > +static unsigned int __intel_ring_space(unsigned int head,
> > +				       unsigned int tail,
> > +				       unsigned int size)
> >  {
> > -	int space = head - tail;
> > -	if (space <= 0)
> > -		space += size;
> > -	return space - I915_RING_FREE_SPACE;
> > +	/* "If the Ring Buffer Head Pointer and the Tail Pointer are on the
> > +	 * same cacheline, the Head Pointer must not be greater than the Tail
> > +	 * Pointer."
> > +	 */
> > +	return (round_down(head, CACHELINE_BYTES) - tail - 8) & (size - 1);
> >  }
> >  
> >  void intel_ring_update_space(struct intel_ring *ring)
> > @@ -1618,12 +1621,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
> >  	GEM_BUG_ON(!req->reserved_space);
> >  
> >  	list_for_each_entry(target, &ring->request_list, ring_link) {
> > -		unsigned space;
> > -
> >  		/* Would completion of this request free enough space? */
> > -		space = __intel_ring_space(target->postfix, ring->emit,
> > -					   ring->size);
> > -		if (space >= bytes)
> > +		if (bytes <= __intel_ring_space(target->postfix,
> > +						ring->emit, ring->size))
> >  			break;
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> > index 31998ea46fb8..e28ffc98c520 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> > @@ -17,17 +17,6 @@
> >  #define CACHELINE_BYTES 64
> >  #define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(uint32_t))
> >  
> > -/*
> > - * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use"
> > - * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use"
> > - * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use"
> > - *
> > - * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same
> > - * cacheline, the Head Pointer must not be greater than the Tail
> > - * Pointer."
> > - */
> > -#define I915_RING_FREE_SPACE 64
> > -
> >  struct intel_hw_status_page {
> >  	struct i915_vma *vma;
> >  	u32 *page_addr;
> > @@ -545,6 +534,19 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
> >  	 */
> >  	GEM_BUG_ON(!IS_ALIGNED(tail, 8));
> >  	GEM_BUG_ON(tail >= ring->size);
> > +
> > +	/* "Ring Buffer Use"
> > +	 *	Gen2 BSpec "1. Programming Environment" / 1.4.4.6
> > +	 *	Gen3 BSpec "1c Memory Interface Functions" / 2.3.4.5
> > +	 *	Gen4+ BSpec "1c Memory Interface and Command Stream" / 5.3.4.5
> > +	 * "If the Ring Buffer Head Pointer and the Tail Pointer are on the
> > +	 * same cacheline, the Head Pointer must not be greater than the Tail
> > +	 * Pointer."
> > +	 */
> > +#define cacheline(a) round_down(a, CACHELINE_BYTES)
> > +	GEM_BUG_ON(cacheline(tail) == cacheline(ring->head) &&
> 
> We are about to set the hw tail. But we are using our
> outdated bookkeepping value of ring head to do the check.
> 
> I am confused. Is this something that can happen only when
> it wraps. And why we dont need to check the HW head?

We know that the real HEAD is at least ring->head. We know that when we
computed the space for the request, we used at most ring->head.
Therefore from our logic, we have treated ring->head == RING_HEAD and
should never violate the cacheline for our own bookkeeping. That it may
not result in the HW tripping up is not as important as confirming our
own logic to prevent the trip.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug
  2017-04-24 12:52   ` Mika Kuoppala
@ 2017-04-24 14:56     ` Chris Wilson
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-24 14:56 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On Mon, Apr 24, 2017 at 03:52:25PM +0300, Mika Kuoppala wrote:
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > Knowing the neighbouring seqno (current on hw, last submitted to hw)
> > provide some useful breadcrumbs to the debug log.
> >
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> 
> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

Pushed the debug patch. I would like to get some traction on the fix in
patch 1... :-p
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
                   ` (5 preceding siblings ...)
  2017-04-24 12:21 ` Mika Kuoppala
@ 2017-04-25 13:00 ` Chris Wilson
  2017-04-25 13:50   ` Mika Kuoppala
  2017-04-25 13:19 ` ✓ Fi.CI.BAT: success for series starting with [v2] drm/i915: Differentiate between sw write location into ring and last hw read (rev2) Patchwork
  7 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-25 13:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Mika Kuoppala

We need to keep track of the last location we ask the hw to read up to
(RING_TAIL) separately from our last write location into the ring, so
that in the event of a GPU reset we do not tell the HW to proceed into
a partially written request (which can happen if that request is waiting
for an external signal before being executed).

v2: Refactor intel_ring_reset() (Mika)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100144
Testcase: igt/gem_exec_fence/await-hang
Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests")
Fixes: d55ac5bf97c6 ("drm/i915: Defer transfer onto execution timeline to actual hw submission")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c    | 16 +++++++++---
 drivers/gpu/drm/i915/i915_guc_submission.c |  4 +--
 drivers/gpu/drm/i915/intel_lrc.c           |  6 ++---
 drivers/gpu/drm/i915/intel_ringbuffer.c    | 41 ++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_ringbuffer.h    | 19 ++++++++++++--
 5 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index e2ec42b2bf24..126cd13abf54 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -283,10 +283,18 @@ static void advance_ring(struct drm_i915_gem_request *request)
 	 * Note this requires that we are always called in request
 	 * completion order.
 	 */
-	if (list_is_last(&request->ring_link, &request->ring->request_list))
-		tail = request->ring->tail;
-	else
+	if (list_is_last(&request->ring_link, &request->ring->request_list)) {
+		/* We may race here with execlists resubmitting this request
+		 * as we retire it. The resubmission will move the ring->tail
+		 * forwards (to request->wa_tail). We either read the
+		 * current value that was written to hw, or the value that
+		 * is just about to be. Either works, if we miss the last two
+		 * noops - they are safe to be replayed on a reset.
+		 */
+		tail = READ_ONCE(request->ring->tail);
+	} else {
 		tail = request->postfix;
+	}
 	list_del(&request->ring_link);
 
 	request->ring->head = tail;
@@ -651,7 +659,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
 	 * GPU processing the request, we never over-estimate the
 	 * position of the head.
 	 */
-	req->head = req->ring->tail;
+	req->head = req->ring->emit;
 
 	/* Check that we didn't interrupt ourselves with a new request */
 	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 1642fff9cf13..ab5140ba108d 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -480,9 +480,7 @@ static void guc_wq_item_append(struct i915_guc_client *client,
 	GEM_BUG_ON(freespace < wqi_size);
 
 	/* The GuC firmware wants the tail index in QWords, not bytes */
-	tail = rq->tail;
-	assert_ring_tail_valid(rq->ring, rq->tail);
-	tail >>= 3;
+	tail = intel_ring_set_tail(rq->ring, rq->tail) >> 3;
 	GEM_BUG_ON(tail > WQ_RING_TAIL_MAX);
 
 	/* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 7df278fe492e..13057a37390b 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -326,8 +326,7 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq)
 		rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
 	u32 *reg_state = ce->lrc_reg_state;
 
-	assert_ring_tail_valid(rq->ring, rq->tail);
-	reg_state[CTX_RING_TAIL+1] = rq->tail;
+	reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
 
 	/* True 32b PPGTT with dynamic page allocation: update PDP
 	 * registers and point the unallocated PDPs to scratch page.
@@ -2054,8 +2053,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
 			ce->state->obj->mm.dirty = true;
 			i915_gem_object_unpin_map(ce->state->obj);
 
-			ce->ring->head = ce->ring->tail = 0;
-			intel_ring_update_space(ce->ring);
+			intel_ring_reset(ce->ring, 0);
 		}
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 32afac6c754f..227dfcf1764e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -49,7 +49,7 @@ static int __intel_ring_space(int head, int tail, int size)
 
 void intel_ring_update_space(struct intel_ring *ring)
 {
-	ring->space = __intel_ring_space(ring->head, ring->tail, ring->size);
+	ring->space = __intel_ring_space(ring->head, ring->emit, ring->size);
 }
 
 static int
@@ -774,8 +774,8 @@ static void i9xx_submit_request(struct drm_i915_gem_request *request)
 
 	i915_gem_request_submit(request);
 
-	assert_ring_tail_valid(request->ring, request->tail);
-	I915_WRITE_TAIL(request->engine, request->tail);
+	I915_WRITE_TAIL(request->engine,
+			intel_ring_set_tail(request->ring, request->tail));
 }
 
 static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
@@ -1319,11 +1319,23 @@ int intel_ring_pin(struct intel_ring *ring,
 	return PTR_ERR(addr);
 }
 
+void intel_ring_reset(struct intel_ring *ring, u32 tail)
+{
+	GEM_BUG_ON(!list_empty(&ring->request_list));
+	ring->tail = tail;
+	ring->head = tail;
+	ring->emit = tail;
+	intel_ring_update_space(ring);
+}
+
 void intel_ring_unpin(struct intel_ring *ring)
 {
 	GEM_BUG_ON(!ring->vma);
 	GEM_BUG_ON(!ring->vaddr);
 
+	/* Discard any unused bytes beyond that submitted to hw. */
+	intel_ring_reset(ring, ring->tail);
+
 	if (i915_vma_is_map_and_fenceable(ring->vma))
 		i915_vma_unpin_iomap(ring->vma);
 	else
@@ -1555,8 +1567,9 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv)
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 
+	/* Restart from the beginning of the rings for convenience */
 	for_each_engine(engine, dev_priv, id)
-		engine->buffer->head = engine->buffer->tail;
+		intel_ring_reset(engine->buffer, 0);
 }
 
 static int ring_request_alloc(struct drm_i915_gem_request *request)
@@ -1609,7 +1622,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 		unsigned space;
 
 		/* Would completion of this request free enough space? */
-		space = __intel_ring_space(target->postfix, ring->tail,
+		space = __intel_ring_space(target->postfix, ring->emit,
 					   ring->size);
 		if (space >= bytes)
 			break;
@@ -1634,8 +1647,8 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 {
 	struct intel_ring *ring = req->ring;
-	int remain_actual = ring->size - ring->tail;
-	int remain_usable = ring->effective_size - ring->tail;
+	int remain_actual = ring->size - ring->emit;
+	int remain_usable = ring->effective_size - ring->emit;
 	int bytes = num_dwords * sizeof(u32);
 	int total_bytes, wait_bytes;
 	bool need_wrap = false;
@@ -1671,17 +1684,17 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 
 	if (unlikely(need_wrap)) {
 		GEM_BUG_ON(remain_actual > ring->space);
-		GEM_BUG_ON(ring->tail + remain_actual > ring->size);
+		GEM_BUG_ON(ring->emit + remain_actual > ring->size);
 
 		/* Fill the tail with MI_NOOP */
-		memset(ring->vaddr + ring->tail, 0, remain_actual);
-		ring->tail = 0;
+		memset(ring->vaddr + ring->emit, 0, remain_actual);
+		ring->emit = 0;
 		ring->space -= remain_actual;
 	}
 
-	GEM_BUG_ON(ring->tail > ring->size - bytes);
-	cs = ring->vaddr + ring->tail;
-	ring->tail += bytes;
+	GEM_BUG_ON(ring->emit > ring->size - bytes);
+	cs = ring->vaddr + ring->emit;
+	ring->emit += bytes;
 	ring->space -= bytes;
 	GEM_BUG_ON(ring->space < 0);
 
@@ -1692,7 +1705,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
 int intel_ring_cacheline_align(struct drm_i915_gem_request *req)
 {
 	int num_dwords =
-		(req->ring->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
+		(req->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
 	u32 *cs;
 
 	if (num_dwords == 0)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 00d36aa4e26d..96710b616efb 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -143,6 +143,7 @@ struct intel_ring {
 
 	u32 head;
 	u32 tail;
+	u32 emit;
 
 	int space;
 	int size;
@@ -494,6 +495,8 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size);
 int intel_ring_pin(struct intel_ring *ring,
 		   struct drm_i915_private *i915,
 		   unsigned int offset_bias);
+void intel_ring_reset(struct intel_ring *ring, u32 tail);
+void intel_ring_update_space(struct intel_ring *ring);
 void intel_ring_unpin(struct intel_ring *ring);
 void intel_ring_free(struct intel_ring *ring);
 
@@ -517,7 +520,7 @@ intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs)
 	 * reserved for the command packet (i.e. the value passed to
 	 * intel_ring_begin()).
 	 */
-	GEM_BUG_ON((req->ring->vaddr + req->ring->tail) != cs);
+	GEM_BUG_ON((req->ring->vaddr + req->ring->emit) != cs);
 }
 
 static inline u32
@@ -546,7 +549,19 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
 	GEM_BUG_ON(tail >= ring->size);
 }
 
-void intel_ring_update_space(struct intel_ring *ring);
+static inline unsigned int
+intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
+{
+	/* Whilst writes to the tail are strictly order, there is no
+	 * serialisation between readers and the writers. The tail may be
+	 * read by i915_gem_request_retire() just as it is being updated
+	 * by execlists, as although the breadcrumb is complete, the context
+	 * switch hasn't been seen.
+	 */
+	assert_ring_tail_valid(ring, tail);
+	ring->tail = tail;
+	return tail;
+}
 
 void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);
 
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* ✓ Fi.CI.BAT: success for series starting with [v2] drm/i915: Differentiate between sw write location into ring and last hw read (rev2)
  2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
                   ` (6 preceding siblings ...)
  2017-04-25 13:00 ` [PATCH v2] " Chris Wilson
@ 2017-04-25 13:19 ` Patchwork
  7 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2017-04-25 13:19 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2] drm/i915: Differentiate between sw write location into ring and last hw read (rev2)
URL   : https://patchwork.freedesktop.org/series/23411/
State : success

== Summary ==

Series 23411v2 Series without cover letter
https://patchwork.freedesktop.org/api/1.0/series/23411/revisions/2/mbox/

Test gem_exec_flush:
        Subgroup basic-batch-kernel-default-uc:
                fail       -> PASS       (fi-snb-2600) fdo#100007

fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007

fi-bdw-5557u     total:278  pass:267  dwarn:0   dfail:0   fail:0   skip:11  time:429s
fi-bdw-gvtdvm    total:278  pass:256  dwarn:8   dfail:0   fail:0   skip:14  time:430s
fi-bsw-n3050     total:278  pass:242  dwarn:0   dfail:0   fail:0   skip:36  time:574s
fi-bxt-j4205     total:278  pass:259  dwarn:0   dfail:0   fail:0   skip:19  time:507s
fi-byt-j1900     total:278  pass:254  dwarn:0   dfail:0   fail:0   skip:24  time:482s
fi-byt-n2820     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:478s
fi-hsw-4770      total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:411s
fi-hsw-4770r     total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:409s
fi-ilk-650       total:278  pass:228  dwarn:0   dfail:0   fail:0   skip:50  time:418s
fi-ivb-3520m     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:493s
fi-ivb-3770      total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:484s
fi-kbl-7500u     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:457s
fi-kbl-7560u     total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:571s
fi-skl-6260u     total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:454s
fi-skl-6700hq    total:278  pass:261  dwarn:0   dfail:0   fail:0   skip:17  time:568s
fi-skl-6700k     total:278  pass:256  dwarn:4   dfail:0   fail:0   skip:18  time:461s
fi-skl-6770hq    total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:491s
fi-skl-gvtdvm    total:278  pass:265  dwarn:0   dfail:0   fail:0   skip:13  time:429s
fi-snb-2520m     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:531s
fi-snb-2600      total:278  pass:249  dwarn:0   dfail:0   fail:0   skip:29  time:404s

babeb6f2b1a90ac0ec1a47bc43a4671649a8fc20 drm-tip: 2017y-04m-25d-10h-04m-12s UTC integration manifest
c7ee119 drm/i915: Compute the ring->space slightly less pessimistically
1e4566e drm/i915: Poison the request before emitting commands
b90ebe1 drm/i915: Differentiate between sw write location into ring and last hw read

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_4544/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-25 13:00 ` [PATCH v2] " Chris Wilson
@ 2017-04-25 13:50   ` Mika Kuoppala
  2017-04-25 14:44     ` Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Mika Kuoppala @ 2017-04-25 13:50 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> We need to keep track of the last location we ask the hw to read up to
> (RING_TAIL) separately from our last write location into the ring, so
> that in the event of a GPU reset we do not tell the HW to proceed into
> a partially written request (which can happen if that request is waiting
> for an external signal before being executed).
>
> v2: Refactor intel_ring_reset() (Mika)
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100144
> Testcase: igt/gem_exec_fence/await-hang
> Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests")
> Fixes: d55ac5bf97c6 ("drm/i915: Defer transfer onto execution timeline to actual hw submission")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Mika Kuoppala <mika.kuoppala@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_gem_request.c    | 16 +++++++++---
>  drivers/gpu/drm/i915/i915_guc_submission.c |  4 +--
>  drivers/gpu/drm/i915/intel_lrc.c           |  6 ++---
>  drivers/gpu/drm/i915/intel_ringbuffer.c    | 41 ++++++++++++++++++++----------
>  drivers/gpu/drm/i915/intel_ringbuffer.h    | 19 ++++++++++++--
>  5 files changed, 59 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index e2ec42b2bf24..126cd13abf54 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -283,10 +283,18 @@ static void advance_ring(struct drm_i915_gem_request *request)
>  	 * Note this requires that we are always called in request
>  	 * completion order.
>  	 */
> -	if (list_is_last(&request->ring_link, &request->ring->request_list))
> -		tail = request->ring->tail;
> -	else
> +	if (list_is_last(&request->ring_link, &request->ring->request_list)) {
> +		/* We may race here with execlists resubmitting this request
> +		 * as we retire it. The resubmission will move the ring->tail
> +		 * forwards (to request->wa_tail). We either read the
> +		 * current value that was written to hw, or the value that
> +		 * is just about to be. Either works, if we miss the last two
> +		 * noops - they are safe to be replayed on a reset.
> +		 */
> +		tail = READ_ONCE(request->ring->tail);
> +	} else {
>  		tail = request->postfix;
> +	}
>  	list_del(&request->ring_link);
>  
>  	request->ring->head = tail;
> @@ -651,7 +659,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>  	 * GPU processing the request, we never over-estimate the
>  	 * position of the head.
>  	 */
> -	req->head = req->ring->tail;
> +	req->head = req->ring->emit;
>  
>  	/* Check that we didn't interrupt ourselves with a new request */
>  	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 1642fff9cf13..ab5140ba108d 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -480,9 +480,7 @@ static void guc_wq_item_append(struct i915_guc_client *client,
>  	GEM_BUG_ON(freespace < wqi_size);
>  
>  	/* The GuC firmware wants the tail index in QWords, not bytes */
> -	tail = rq->tail;
> -	assert_ring_tail_valid(rq->ring, rq->tail);
> -	tail >>= 3;
> +	tail = intel_ring_set_tail(rq->ring, rq->tail) >> 3;
>  	GEM_BUG_ON(tail > WQ_RING_TAIL_MAX);
>  
>  	/* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 7df278fe492e..13057a37390b 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -326,8 +326,7 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq)
>  		rq->ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
>  	u32 *reg_state = ce->lrc_reg_state;
>  
> -	assert_ring_tail_valid(rq->ring, rq->tail);
> -	reg_state[CTX_RING_TAIL+1] = rq->tail;
> +	reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
>  
>  	/* True 32b PPGTT with dynamic page allocation: update PDP
>  	 * registers and point the unallocated PDPs to scratch page.
> @@ -2054,8 +2053,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
>  			ce->state->obj->mm.dirty = true;
>  			i915_gem_object_unpin_map(ce->state->obj);
>  
> -			ce->ring->head = ce->ring->tail = 0;
> -			intel_ring_update_space(ce->ring);
> +			intel_ring_reset(ce->ring, 0);
>  		}
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 32afac6c754f..227dfcf1764e 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -49,7 +49,7 @@ static int __intel_ring_space(int head, int tail, int size)
>  
>  void intel_ring_update_space(struct intel_ring *ring)
>  {
> -	ring->space = __intel_ring_space(ring->head, ring->tail, ring->size);
> +	ring->space = __intel_ring_space(ring->head, ring->emit, ring->size);
>  }
>  
>  static int
> @@ -774,8 +774,8 @@ static void i9xx_submit_request(struct drm_i915_gem_request *request)
>  
>  	i915_gem_request_submit(request);
>  
> -	assert_ring_tail_valid(request->ring, request->tail);
> -	I915_WRITE_TAIL(request->engine, request->tail);
> +	I915_WRITE_TAIL(request->engine,
> +			intel_ring_set_tail(request->ring, request->tail));
>  }
>  
>  static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
> @@ -1319,11 +1319,23 @@ int intel_ring_pin(struct intel_ring *ring,
>  	return PTR_ERR(addr);
>  }
>  
> +void intel_ring_reset(struct intel_ring *ring, u32 tail)
> +{
> +	GEM_BUG_ON(!list_empty(&ring->request_list));
> +	ring->tail = tail;
> +	ring->head = tail;
> +	ring->emit = tail;
> +	intel_ring_update_space(ring);
> +}
> +
>  void intel_ring_unpin(struct intel_ring *ring)
>  {
>  	GEM_BUG_ON(!ring->vma);
>  	GEM_BUG_ON(!ring->vaddr);
>  
> +	/* Discard any unused bytes beyond that submitted to hw. */
> +	intel_ring_reset(ring, ring->tail);
> +
>  	if (i915_vma_is_map_and_fenceable(ring->vma))
>  		i915_vma_unpin_iomap(ring->vma);
>  	else
> @@ -1555,8 +1567,9 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv)
>  	struct intel_engine_cs *engine;
>  	enum intel_engine_id id;
>  
> +	/* Restart from the beginning of the rings for convenience */
>  	for_each_engine(engine, dev_priv, id)
> -		engine->buffer->head = engine->buffer->tail;
> +		intel_ring_reset(engine->buffer, 0);
>  }
>  
>  static int ring_request_alloc(struct drm_i915_gem_request *request)
> @@ -1609,7 +1622,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
>  		unsigned space;
>  
>  		/* Would completion of this request free enough space? */
> -		space = __intel_ring_space(target->postfix, ring->tail,
> +		space = __intel_ring_space(target->postfix, ring->emit,
>  					   ring->size);
>  		if (space >= bytes)
>  			break;
> @@ -1634,8 +1647,8 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
>  u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  {
>  	struct intel_ring *ring = req->ring;
> -	int remain_actual = ring->size - ring->tail;
> -	int remain_usable = ring->effective_size - ring->tail;
> +	int remain_actual = ring->size - ring->emit;
> +	int remain_usable = ring->effective_size - ring->emit;
>  	int bytes = num_dwords * sizeof(u32);
>  	int total_bytes, wait_bytes;
>  	bool need_wrap = false;
> @@ -1671,17 +1684,17 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  
>  	if (unlikely(need_wrap)) {
>  		GEM_BUG_ON(remain_actual > ring->space);
> -		GEM_BUG_ON(ring->tail + remain_actual > ring->size);
> +		GEM_BUG_ON(ring->emit + remain_actual > ring->size);
>  
>  		/* Fill the tail with MI_NOOP */
> -		memset(ring->vaddr + ring->tail, 0, remain_actual);
> -		ring->tail = 0;
> +		memset(ring->vaddr + ring->emit, 0, remain_actual);
> +		ring->emit = 0;
>  		ring->space -= remain_actual;
>  	}
>  
> -	GEM_BUG_ON(ring->tail > ring->size - bytes);
> -	cs = ring->vaddr + ring->tail;
> -	ring->tail += bytes;
> +	GEM_BUG_ON(ring->emit > ring->size - bytes);
> +	cs = ring->vaddr + ring->emit;
> +	ring->emit += bytes;
>  	ring->space -= bytes;
>  	GEM_BUG_ON(ring->space < 0);
>  
> @@ -1692,7 +1705,7 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords)
>  int intel_ring_cacheline_align(struct drm_i915_gem_request *req)
>  {
>  	int num_dwords =
> -		(req->ring->tail & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
> +		(req->ring->emit & (CACHELINE_BYTES - 1)) / sizeof(uint32_t);
>  	u32 *cs;
>  
>  	if (num_dwords == 0)
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 00d36aa4e26d..96710b616efb 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -143,6 +143,7 @@ struct intel_ring {
>  
>  	u32 head;
>  	u32 tail;
> +	u32 emit;
>  
>  	int space;
>  	int size;
> @@ -494,6 +495,8 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size);
>  int intel_ring_pin(struct intel_ring *ring,
>  		   struct drm_i915_private *i915,
>  		   unsigned int offset_bias);
> +void intel_ring_reset(struct intel_ring *ring, u32 tail);
> +void intel_ring_update_space(struct intel_ring *ring);
>  void intel_ring_unpin(struct intel_ring *ring);
>  void intel_ring_free(struct intel_ring *ring);
>  
> @@ -517,7 +520,7 @@ intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs)
>  	 * reserved for the command packet (i.e. the value passed to
>  	 * intel_ring_begin()).
>  	 */
> -	GEM_BUG_ON((req->ring->vaddr + req->ring->tail) != cs);
> +	GEM_BUG_ON((req->ring->vaddr + req->ring->emit) != cs);
>  }
>  
>  static inline u32
> @@ -546,7 +549,19 @@ assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
>  	GEM_BUG_ON(tail >= ring->size);
>  }
>  
> -void intel_ring_update_space(struct intel_ring *ring);
> +static inline unsigned int
> +intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
> +{
> +	/* Whilst writes to the tail are strictly order, there is no
> +	 * serialisation between readers and the writers. The tail may be
> +	 * read by i915_gem_request_retire() just as it is being updated
> +	 * by execlists, as although the breadcrumb is complete, the context
> +	 * switch hasn't been seen.
> +	 */
> +	assert_ring_tail_valid(ring, tail);
> +	ring->tail = tail;
> +	return tail;
> +}
>  
>  void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);
>  
> -- 
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2] drm/i915: Differentiate between sw write location into ring and last hw read
  2017-04-25 13:50   ` Mika Kuoppala
@ 2017-04-25 14:44     ` Chris Wilson
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-25 14:44 UTC (permalink / raw)
  To: Mika Kuoppala; +Cc: intel-gfx

On Tue, Apr 25, 2017 at 04:50:15PM +0300, Mika Kuoppala wrote:
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > We need to keep track of the last location we ask the hw to read up to
> > (RING_TAIL) separately from our last write location into the ring, so
> > that in the event of a GPU reset we do not tell the HW to proceed into
> > a partially written request (which can happen if that request is waiting
> > for an external signal before being executed).
> >
> > v2: Refactor intel_ring_reset() (Mika)
> >
> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100144
> > Testcase: igt/gem_exec_fence/await-hang
> > Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests")
> > Fixes: d55ac5bf97c6 ("drm/i915: Defer transfer onto execution timeline to actual hw submission")
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > Cc: Mika Kuoppala <mika.kuoppala@intel.com>
> 
> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

Pushed the first 2 to get the bug fix. That just leaves the
micro-optimisation of intel_ring_space.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2017-04-25 14:44 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-23 17:06 [PATCH 1/4] drm/i915: Differentiate between sw write location into ring and last hw read Chris Wilson
2017-04-23 17:06 ` [PATCH 2/4] drm/i915: Poison the request before emitting commands Chris Wilson
2017-04-24 12:29   ` Mika Kuoppala
2017-04-24 12:50     ` Chris Wilson
2017-04-23 17:06 ` [PATCH 3/4] drm/i915: Compute the ring->space slightly less pessimistically Chris Wilson
2017-04-24 12:37   ` Mika Kuoppala
2017-04-24 12:52     ` Chris Wilson
2017-04-23 17:06 ` [PATCH 4/4] drm/i915: Include interesting seqno in the missed breadcrumb debug Chris Wilson
2017-04-24 12:52   ` Mika Kuoppala
2017-04-24 14:56     ` Chris Wilson
2017-04-23 17:24 ` ✓ Fi.CI.BAT: success for series starting with [1/4] drm/i915: Differentiate between sw write location into ring and last hw read Patchwork
2017-04-23 17:52 ` [PATCH 1/4] " Chris Wilson
2017-04-24 12:21 ` Mika Kuoppala
2017-04-24 12:32   ` Chris Wilson
2017-04-24 12:41     ` Chris Wilson
2017-04-25 13:00 ` [PATCH v2] " Chris Wilson
2017-04-25 13:50   ` Mika Kuoppala
2017-04-25 14:44     ` Chris Wilson
2017-04-25 13:19 ` ✓ Fi.CI.BAT: success for series starting with [v2] drm/i915: Differentiate between sw write location into ring and last hw read (rev2) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.