All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 03/18] drm/i915/ringbuffer: Fix context restore upon reset
Date: Fri,  8 Jun 2018 13:55:47 +0100	[thread overview]
Message-ID: <20180608125602.17693-4-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20180608125602.17693-1-chris@chris-wilson.co.uk>

The discovery with trying to enable full-ppgtt was that we were
completely failing to the load both the mm and context following the
reset. Although we were performing mmio to set the PP_DIR (per-process
GTT) and CCID (context), these were taking no effect (the assumption was
that this would trigger reload of the context and restore the page
tables). It was not until we performed the LRI + MI_SET_CONTEXT in a
following context switch would anything occur.

Since we are then required to reset the context image and PP_DIR using
CS commands, we place those commands into every batch. The hardware
should recognise the no-ops and eliminate the expensive context loads,
but we still have to pay the cost of using cross-powerwell register
writes. In practice, this has no effect on actual context switch times,
and only adds a few hundred nanoseconds to no-op switches. We can improve
the latter by eliminating the w/a around known no-op switches, but there
is an ulterior motive to keeping them.

Always emitting the context switch at the beginning of the request (and
relying on HW to skip unneeded switches) does have one key advantage.
Should we implement request reordering on Haswell, we will not know in
advance what the previous executing context was on the GPU and so we
would not be able to elide the MI_SET_CONTEXT commands ourselves and
always have to emit them. Having our hand forced now actually prepares
us for later.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/i915_request.c     |  2 +
 drivers/gpu/drm/i915/i915_request.h     |  3 +
 drivers/gpu/drm/i915/intel_engine_cs.c  |  3 -
 drivers/gpu/drm/i915/intel_ringbuffer.c | 75 ++++++++-----------------
 drivers/gpu/drm/i915/intel_ringbuffer.h |  9 ---
 5 files changed, 28 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index f187250e60c6..9092f5464c24 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -817,6 +817,8 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 	/* Keep a second pin for the dual retirement along engine and ring */
 	__intel_context_pin(ce);
 
+	rq->infix = rq->ring->emit; /* end of header; start of user payload */
+
 	/* Check that we didn't interrupt ourselves with a new request */
 	GEM_BUG_ON(rq->timeline->seqno != rq->fence.seqno);
 	return rq;
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 491ff81d0fea..0e9aba53d0e4 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -134,6 +134,9 @@ struct i915_request {
 	/** Position in the ring of the start of the request */
 	u32 head;
 
+	/** Position in the ring of the start of the user packets */
+	u32 infix;
+
 	/**
 	 * Position in the ring of the start of the postfix.
 	 * This is required to calculate the maximum available ring space
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 2ec2e60dc670..d1cf8b4926ab 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1168,9 +1168,6 @@ void intel_engine_lost_context(struct intel_engine_cs *engine)
 
 	lockdep_assert_held(&engine->i915->drm.struct_mutex);
 
-	engine->legacy_active_context = NULL;
-	engine->legacy_active_ppgtt = NULL;
-
 	ce = fetch_and_zero(&engine->last_retired_context);
 	if (ce)
 		intel_context_unpin(ce);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 332d97bc5c27..1b3805adbd57 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -541,6 +541,21 @@ static struct i915_request *reset_prepare(struct intel_engine_cs *engine)
 	return i915_gem_find_active_request(engine);
 }
 
+static void skip_request(struct i915_request *request)
+{
+	void *vaddr = request->ring->vaddr;
+	u32 head;
+
+	head = request->infix;
+	if (request->postfix < head) {
+		memset32(vaddr + head, MI_NOOP,
+			 (request->ring->size - head) / sizeof(u32));
+		head = 0;
+	}
+	memset32(vaddr + head, MI_NOOP,
+		 (request->postfix - head) / sizeof(u32));
+}
+
 static void reset_ring(struct intel_engine_cs *engine,
 		       struct i915_request *request)
 {
@@ -570,42 +585,10 @@ static void reset_ring(struct intel_engine_cs *engine,
 	 * the restored context.
 	 */
 	if (request) {
-		struct drm_i915_private *dev_priv = request->i915;
-		struct intel_context *ce = request->hw_context;
-		struct i915_hw_ppgtt *ppgtt;
-
-		if (ce->state) {
-			I915_WRITE(CCID,
-				   i915_ggtt_offset(ce->state) |
-				   BIT(8) /* must be set! */ |
-				   CCID_EXTENDED_STATE_SAVE |
-				   CCID_EXTENDED_STATE_RESTORE |
-				   CCID_EN);
-		}
-
-		ppgtt = request->gem_context->ppgtt ?: engine->i915->mm.aliasing_ppgtt;
-		if (ppgtt) {
-			u32 pd_offset = ppgtt->pd.base.ggtt_offset << 10;
-
-			I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G);
-			I915_WRITE(RING_PP_DIR_BASE(engine), pd_offset);
-
-			/* Wait for the PD reload to complete */
-			if (intel_wait_for_register(dev_priv,
-						    RING_PP_DIR_BASE(engine),
-						    BIT(0), 0,
-						    10))
-				DRM_ERROR("Wait for reload of ppgtt page-directory timed out\n");
-
-			ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
-		}
-
 		/* If the rq hung, jump to its breadcrumb and skip the batch */
+		request->ring->head = request->head;
 		if (request->fence.error == -EIO)
-			request->ring->head = request->postfix;
-	} else {
-		engine->legacy_active_context = NULL;
-		engine->legacy_active_ppgtt = NULL;
+			skip_request(request);
 	}
 }
 
@@ -1589,31 +1572,25 @@ static int switch_context(struct i915_request *rq)
 	struct i915_gem_context *to_ctx = rq->gem_context;
 	struct i915_hw_ppgtt *to_mm =
 		to_ctx->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
-	struct i915_gem_context *from_ctx = engine->legacy_active_context;
-	struct i915_hw_ppgtt *from_mm = engine->legacy_active_ppgtt;
 	u32 hw_flags = 0;
 	int ret, i;
 
 	lockdep_assert_held(&rq->i915->drm.struct_mutex);
 	GEM_BUG_ON(HAS_EXECLISTS(rq->i915));
 
-	if (to_mm != from_mm ||
-	    (to_mm && intel_engine_flag(engine) & to_mm->pd_dirty_rings)) {
+	if (to_mm) {
 		trace_switch_mm(engine, to_ctx);
 		ret = to_mm->switch_mm(to_mm, rq);
 		if (ret)
 			goto err;
 
-		to_mm->pd_dirty_rings &= ~intel_engine_flag(engine);
-		engine->legacy_active_ppgtt = to_mm;
-
-		if (to_ctx == from_ctx) {
+		if (intel_engine_flag(engine) & to_mm->pd_dirty_rings) {
 			hw_flags = MI_FORCE_RESTORE;
-			from_ctx = NULL;
+			to_mm->pd_dirty_rings &= ~intel_engine_flag(engine);
 		}
 	}
 
-	if (rq->hw_context->state && to_ctx != from_ctx) {
+	if (rq->hw_context->state) {
 		GEM_BUG_ON(engine->id != RCS);
 
 		/*
@@ -1628,9 +1605,7 @@ static int switch_context(struct i915_request *rq)
 
 		ret = mi_set_context(rq, hw_flags);
 		if (ret)
-			goto err_mm;
-
-		engine->legacy_active_context = to_ctx;
+			goto err;
 	}
 
 	if (to_ctx->remap_slice) {
@@ -1640,7 +1615,7 @@ static int switch_context(struct i915_request *rq)
 
 			ret = remap_l3(rq, i);
 			if (ret)
-				goto err_ctx;
+				goto err;
 		}
 
 		to_ctx->remap_slice = 0;
@@ -1648,10 +1623,6 @@ static int switch_context(struct i915_request *rq)
 
 	return 0;
 
-err_ctx:
-	engine->legacy_active_context = from_ctx;
-err_mm:
-	engine->legacy_active_ppgtt = from_mm;
 err:
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index acef385c4c80..b44c67849749 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -557,15 +557,6 @@ struct intel_engine_cs {
 	 */
 	struct intel_context *last_retired_context;
 
-	/* We track the current MI_SET_CONTEXT in order to eliminate
-	 * redudant context switches. This presumes that requests are not
-	 * reordered! Or when they are the tracking is updated along with
-	 * the emission of individual requests into the legacy command
-	 * stream (ring).
-	 */
-	struct i915_gem_context *legacy_active_context;
-	struct i915_hw_ppgtt *legacy_active_ppgtt;
-
 	/* status_notifier: list of callbacks for context-switch changes */
 	struct atomic_notifier_head context_status_notifier;
 
-- 
2.17.1

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

  parent reply	other threads:[~2018-06-08 12:56 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-08 12:55 Haswell full-ppgtt, no really Chris Wilson
2018-06-08 12:55 ` [PATCH 01/18] drm/i915: Apply batch location restrictions before pinning Chris Wilson
2018-06-08 12:55 ` [PATCH 02/18] drm/i915/ringbuffer: Brute force context restore Chris Wilson
2018-06-08 13:52   ` Mika Kuoppala
2018-06-08 14:00     ` Chris Wilson
2018-06-08 12:55 ` Chris Wilson [this message]
2018-06-08 14:26   ` [PATCH 03/18] drm/i915/ringbuffer: Fix context restore upon reset Chris Wilson
2018-06-08 17:26   ` [PATCH v2] " Chris Wilson
2018-06-08 12:55 ` [PATCH 04/18] drm/i915/gtt: Invalidate GGTT caches after writing the gen6 page directories Chris Wilson
2018-06-08 12:55 ` [PATCH 05/18] drm/i915/gtt: Subclass gen6_hw_ppgtt Chris Wilson
2018-06-08 12:55 ` [PATCH 06/18] drm/i915/gtt: Onionify error handling for gen6_ppgtt_create Chris Wilson
2018-06-08 12:55 ` [PATCH 07/18] drm/i915/gtt: Reorder aliasing_ppgtt fini Chris Wilson
2018-06-08 12:55 ` [PATCH 08/18] drm/i915/gtt: Make gen6 page directories evictable Chris Wilson
2018-06-08 13:10   ` [PATCH] " Chris Wilson
2018-06-08 12:55 ` [PATCH 09/18] drm/i915/gtt: Only keep gen6 page directories pinned while active Chris Wilson
2018-06-08 12:55 ` [PATCH 10/18] drm/i915/gtt: Lazily allocate page directories for gen7 Chris Wilson
2018-06-08 14:37   ` Matthew Auld
2018-06-08 14:43     ` Chris Wilson
2018-06-08 12:55 ` [PATCH 11/18] drm/i915/gtt: Free unused page tables on unbind the context Chris Wilson
2018-06-08 12:55 ` [PATCH 12/18] drm/i915/gtt: Skip initializing PT with scratch if full Chris Wilson
2018-06-08 12:55 ` [PATCH 13/18] drm/i915/gtt: Cache the PTE encoding of the scratch page Chris Wilson
2018-06-08 12:55 ` [PATCH 14/18] drm/i915/gtt: Reduce a pair of runtime asserts Chris Wilson
2018-06-08 12:55 ` [PATCH 15/18] drm/i915/gtt: Skip clearing the GGTT under gen6+ full-ppgtt Chris Wilson
2018-06-08 12:56 ` [PATCH 16/18] drm/i915/gtt: Remove redundant hsw_mm_switch() Chris Wilson
2018-06-08 14:03   ` Mika Kuoppala
2018-06-08 12:56 ` [PATCH 17/18] drm/i915/gtt: Remove vgpu check for gen6 Chris Wilson
2018-06-08 14:06   ` Mika Kuoppala
2018-06-08 12:56 ` [PATCH 18/18] RFT drm/i915/gtt: Enable full-ppgtt by default everywhere Chris Wilson
2018-06-08 13:25 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/18] drm/i915: Apply batch location restrictions before pinning (rev2) Patchwork
2018-06-08 13:30 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-06-08 13:41 ` ✓ Fi.CI.BAT: success " Patchwork
2018-06-08 16:23 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-06-08 16:36   ` Chris Wilson
2018-06-08 17:09     ` Chris Wilson
2018-06-08 18:03 ` ✗ Fi.CI.BAT: failure for series starting with [01/18] drm/i915: Apply batch location restrictions before pinning (rev3) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180608125602.17693-4-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.