All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches
@ 2017-11-21  9:33 Chris Wilson
  2017-11-21  9:33 ` [PATCH 2/2] drm/i915: Move mi_set_context() into the legacy ringbuffer submission Chris Wilson
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Chris Wilson @ 2017-11-21  9:33 UTC (permalink / raw)
  To: intel-gfx

The legacy context switch for ringbuffer submission is multistaged,
where each of those stages may fail. However, we were updating global
state after some stages, and so we had to force the incomplete request
to be submitted because we could not unwind. Save the global state
before performing the switches, and so enable us to unwind back to the
previous global state should any phase fail. We then must cancel the
request instead of submitting it should the construction fail.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 168 ++++++++++----------------------
 drivers/gpu/drm/i915/i915_gem_request.c |  18 ++--
 drivers/gpu/drm/i915/intel_ringbuffer.c |   1 +
 drivers/gpu/drm/i915/intel_ringbuffer.h |   1 +
 4 files changed, 62 insertions(+), 126 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 6ca56e482d79..f63bec08cc85 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -507,6 +507,7 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
 
 	for_each_engine(engine, dev_priv, id) {
 		engine->legacy_active_context = NULL;
+		engine->legacy_active_ppgtt = NULL;
 
 		if (!engine->last_retired_context)
 			continue;
@@ -681,68 +682,48 @@ static int remap_l3(struct drm_i915_gem_request *req, int slice)
 	return 0;
 }
 
-static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt,
-				   struct intel_engine_cs *engine,
-				   struct i915_gem_context *to)
-{
-	if (to->remap_slice)
-		return false;
-
-	if (ppgtt && (intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
-		return false;
-
-	return to == engine->legacy_active_context;
-}
-
-static bool
-needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine)
-{
-	struct i915_gem_context *from = engine->legacy_active_context;
-
-	if (!ppgtt)
-		return false;
-
-	/* Always load the ppgtt on first use */
-	if (!from)
-		return true;
-
-	/* Same context without new entries, skip */
-	if ((!from->ppgtt || from->ppgtt == ppgtt) &&
-	    !(intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
-		return false;
-
-	if (engine->id != RCS)
-		return true;
-
-	return true;
-}
-
-static int do_rcs_switch(struct drm_i915_gem_request *req)
+/**
+ * i915_switch_context() - perform a GPU context switch.
+ * @rq: request for which we'll execute the context switch
+ *
+ * The context life cycle is simple. The context refcount is incremented and
+ * decremented by 1 and create and destroy. If the context is in use by the GPU,
+ * it will have a refcount > 1. This allows us to destroy the context abstract
+ * object while letting the normal object tracking destroy the backing BO.
+ *
+ * This function should not be used in execlists mode.  Instead the context is
+ * switched by writing to the ELSP and requests keep a reference to their
+ * context.
+ */
+int i915_switch_context(struct drm_i915_gem_request *rq)
 {
-	struct i915_gem_context *to = req->ctx;
-	struct intel_engine_cs *engine = req->engine;
-	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
-	struct i915_gem_context *from = engine->legacy_active_context;
-	u32 hw_flags;
+	struct intel_engine_cs *engine = rq->engine;
+	struct i915_gem_context *to = rq->ctx;
+	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
+	struct i915_gem_context *saved_ctx = engine->legacy_active_context;
+	struct i915_hw_ppgtt *saved_mm = engine->legacy_active_ppgtt;
+	u32 hw_flags = 0;
 	int ret, i;
 
-	GEM_BUG_ON(engine->id != RCS);
-
-	if (skip_rcs_switch(ppgtt, engine, to))
-		return 0;
+	lockdep_assert_held(&rq->i915->drm.struct_mutex);
+	GEM_BUG_ON(HAS_EXECLISTS(rq->i915));
 
-	if (needs_pd_load_pre(ppgtt, engine)) {
-		/* Older GENs and non render rings still want the load first,
-		 * "PP_DCLV followed by PP_DIR_BASE register through Load
-		 * Register Immediate commands in Ring Buffer before submitting
-		 * a context."*/
+	if (ppgtt != saved_mm ||
+	    (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) {
 		trace_switch_mm(engine, to);
-		ret = ppgtt->switch_mm(ppgtt, req);
+		ret = ppgtt->switch_mm(ppgtt, rq);
 		if (ret)
-			return ret;
+			goto err;
+
+		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
+		engine->legacy_active_ppgtt = ppgtt;
+		hw_flags = MI_FORCE_RESTORE;
 	}
 
-	if (i915_gem_context_is_kernel(to))
+	if (to->engine[engine->id].state &&
+	    (to != saved_ctx || hw_flags & MI_FORCE_RESTORE)) {
+		GEM_BUG_ON(engine->id != RCS);
+
 		/*
 		 * The kernel context(s) is treated as pure scratch and is not
 		 * expected to retain any state (as we sacrifice it during
@@ -750,78 +731,37 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
 		 * as nothing actually executes using the kernel context; it
 		 * is purely used for flushing user contexts.
 		 */
-		hw_flags = MI_RESTORE_INHIBIT;
-	else if (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)
-		hw_flags = MI_FORCE_RESTORE;
-	else
-		hw_flags = 0;
+		if (i915_gem_context_is_kernel(to))
+			hw_flags = MI_RESTORE_INHIBIT;
 
-	if (to != from || (hw_flags & MI_FORCE_RESTORE)) {
-		ret = mi_set_context(req, hw_flags);
+		ret = mi_set_context(rq, hw_flags);
 		if (ret)
-			return ret;
+			goto err_mm;
 
 		engine->legacy_active_context = to;
 	}
 
-	if (ppgtt)
-		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
-
-	for (i = 0; i < MAX_L3_SLICES; i++) {
-		if (!(to->remap_slice & (1<<i)))
-			continue;
-
-		ret = remap_l3(req, i);
-		if (ret)
-			return ret;
-
-		to->remap_slice &= ~(1<<i);
-	}
-
-	return 0;
-}
-
-/**
- * i915_switch_context() - perform a GPU context switch.
- * @req: request for which we'll execute the context switch
- *
- * The context life cycle is simple. The context refcount is incremented and
- * decremented by 1 and create and destroy. If the context is in use by the GPU,
- * it will have a refcount > 1. This allows us to destroy the context abstract
- * object while letting the normal object tracking destroy the backing BO.
- *
- * This function should not be used in execlists mode.  Instead the context is
- * switched by writing to the ELSP and requests keep a reference to their
- * context.
- */
-int i915_switch_context(struct drm_i915_gem_request *req)
-{
-	struct intel_engine_cs *engine = req->engine;
-
-	lockdep_assert_held(&req->i915->drm.struct_mutex);
-	GEM_BUG_ON(HAS_EXECLISTS(req->i915));
+	if (to->remap_slice) {
+		for (i = 0; i < MAX_L3_SLICES; i++) {
+			if (!(to->remap_slice & BIT(i)))
+				continue;
 
-	if (!req->ctx->engine[engine->id].state) {
-		struct i915_gem_context *to = req->ctx;
-		struct i915_hw_ppgtt *ppgtt =
-			to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
-
-		if (needs_pd_load_pre(ppgtt, engine)) {
-			int ret;
-
-			trace_switch_mm(engine, to);
-			ret = ppgtt->switch_mm(ppgtt, req);
+			ret = remap_l3(rq, i);
 			if (ret)
-				return ret;
-
-			ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
+				goto err_ctx;
 		}
 
-		engine->legacy_active_context = to;
-		return 0;
+		to->remap_slice = 0;
 	}
 
-	return do_rcs_switch(req);
+	return 0;
+
+err_ctx:
+	engine->legacy_active_context = saved_ctx;
+err_mm:
+	engine->legacy_active_ppgtt = saved_mm;
+err:
+	return ret;
 }
 
 static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 86e2346357cf..2749e4735563 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -718,25 +718,19 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
 	/* Unconditionally invalidate GPU caches and TLBs. */
 	ret = engine->emit_flush(req, EMIT_INVALIDATE);
 	if (ret)
-		goto err_ctx;
+		goto err_unwind;
 
 	ret = engine->request_alloc(req);
-	if (ret) {
-		/*
-		 * Past the point-of-no-return. Since we may have updated
-		 * global state after partially completing the request alloc,
-		 * we need to commit any commands so far emitted in the
-		 * request to the HW.
-		 */
-		__i915_add_request(req, false);
-		return ERR_PTR(ret);
-	}
+	if (ret)
+		goto err_unwind;
 
 	/* Check that we didn't interrupt ourselves with a new request */
 	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
 	return req;
 
-err_ctx:
+err_unwind:
+	req->ring->emit = req->head;
+
 	/* Make sure we didn't add ourselves to external state before freeing */
 	GEM_BUG_ON(!list_empty(&req->active_list));
 	GEM_BUG_ON(!list_empty(&req->priotree.signalers_list));
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index bfa11a84e476..a904b0353bec 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -591,6 +591,7 @@ static void reset_ring_common(struct intel_engine_cs *engine,
 			request->ring->head = request->postfix;
 	} else {
 		engine->legacy_active_context = NULL;
+		engine->legacy_active_ppgtt = NULL;
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index d16e32adf19a..cbc9c36f675e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -494,6 +494,7 @@ struct intel_engine_cs {
 	 * 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.15.0

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

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

* [PATCH 2/2] drm/i915: Move mi_set_context() into the legacy ringbuffer submission
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
@ 2017-11-21  9:33 ` Chris Wilson
  2017-11-21  9:54 ` ✗ Fi.CI.BAT: warning for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches Patchwork
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Wilson @ 2017-11-21  9:33 UTC (permalink / raw)
  To: intel-gfx

The legacy i915_switch_context() is only applicable to the legacy
ringbuffer submission method, so move it from the general
i915_gem_context.c to intel_ringbuffer.c (rename pending!).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 197 --------------------------------
 drivers/gpu/drm/i915/intel_ringbuffer.c | 185 +++++++++++++++++++++++++++++-
 2 files changed, 184 insertions(+), 198 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index f63bec08cc85..aee0f6d72d33 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -567,203 +567,6 @@ void i915_gem_context_close(struct drm_file *file)
 	idr_destroy(&file_priv->context_idr);
 }
 
-static inline int
-mi_set_context(struct drm_i915_gem_request *req, u32 flags)
-{
-	struct drm_i915_private *dev_priv = req->i915;
-	struct intel_engine_cs *engine = req->engine;
-	enum intel_engine_id id;
-	const int num_rings =
-		/* Use an extended w/a on gen7 if signalling from other rings */
-		(HAS_LEGACY_SEMAPHORES(dev_priv) && IS_GEN7(dev_priv)) ?
-		INTEL_INFO(dev_priv)->num_rings - 1 :
-		0;
-	int len;
-	u32 *cs;
-
-	flags |= MI_MM_SPACE_GTT;
-	if (IS_HASWELL(dev_priv))
-		/* These flags are for resource streamer on HSW+ */
-		flags |= HSW_MI_RS_SAVE_STATE_EN | HSW_MI_RS_RESTORE_STATE_EN;
-	else
-		flags |= MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN;
-
-	len = 4;
-	if (IS_GEN7(dev_priv))
-		len += 2 + (num_rings ? 4*num_rings + 6 : 0);
-
-	cs = intel_ring_begin(req, len);
-	if (IS_ERR(cs))
-		return PTR_ERR(cs);
-
-	/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */
-	if (IS_GEN7(dev_priv)) {
-		*cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
-		if (num_rings) {
-			struct intel_engine_cs *signaller;
-
-			*cs++ = MI_LOAD_REGISTER_IMM(num_rings);
-			for_each_engine(signaller, dev_priv, id) {
-				if (signaller == engine)
-					continue;
-
-				*cs++ = i915_mmio_reg_offset(
-					   RING_PSMI_CTL(signaller->mmio_base));
-				*cs++ = _MASKED_BIT_ENABLE(
-						GEN6_PSMI_SLEEP_MSG_DISABLE);
-			}
-		}
-	}
-
-	*cs++ = MI_NOOP;
-	*cs++ = MI_SET_CONTEXT;
-	*cs++ = i915_ggtt_offset(req->ctx->engine[RCS].state) | flags;
-	/*
-	 * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP
-	 * WaMiSetContext_Hang:snb,ivb,vlv
-	 */
-	*cs++ = MI_NOOP;
-
-	if (IS_GEN7(dev_priv)) {
-		if (num_rings) {
-			struct intel_engine_cs *signaller;
-			i915_reg_t last_reg = {}; /* keep gcc quiet */
-
-			*cs++ = MI_LOAD_REGISTER_IMM(num_rings);
-			for_each_engine(signaller, dev_priv, id) {
-				if (signaller == engine)
-					continue;
-
-				last_reg = RING_PSMI_CTL(signaller->mmio_base);
-				*cs++ = i915_mmio_reg_offset(last_reg);
-				*cs++ = _MASKED_BIT_DISABLE(
-						GEN6_PSMI_SLEEP_MSG_DISABLE);
-			}
-
-			/* Insert a delay before the next switch! */
-			*cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
-			*cs++ = i915_mmio_reg_offset(last_reg);
-			*cs++ = i915_ggtt_offset(engine->scratch);
-			*cs++ = MI_NOOP;
-		}
-		*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
-	}
-
-	intel_ring_advance(req, cs);
-
-	return 0;
-}
-
-static int remap_l3(struct drm_i915_gem_request *req, int slice)
-{
-	u32 *cs, *remap_info = req->i915->l3_parity.remap_info[slice];
-	int i;
-
-	if (!remap_info)
-		return 0;
-
-	cs = intel_ring_begin(req, GEN7_L3LOG_SIZE/4 * 2 + 2);
-	if (IS_ERR(cs))
-		return PTR_ERR(cs);
-
-	/*
-	 * Note: We do not worry about the concurrent register cacheline hang
-	 * here because no other code should access these registers other than
-	 * at initialization time.
-	 */
-	*cs++ = MI_LOAD_REGISTER_IMM(GEN7_L3LOG_SIZE/4);
-	for (i = 0; i < GEN7_L3LOG_SIZE/4; i++) {
-		*cs++ = i915_mmio_reg_offset(GEN7_L3LOG(slice, i));
-		*cs++ = remap_info[i];
-	}
-	*cs++ = MI_NOOP;
-	intel_ring_advance(req, cs);
-
-	return 0;
-}
-
-/**
- * i915_switch_context() - perform a GPU context switch.
- * @rq: request for which we'll execute the context switch
- *
- * The context life cycle is simple. The context refcount is incremented and
- * decremented by 1 and create and destroy. If the context is in use by the GPU,
- * it will have a refcount > 1. This allows us to destroy the context abstract
- * object while letting the normal object tracking destroy the backing BO.
- *
- * This function should not be used in execlists mode.  Instead the context is
- * switched by writing to the ELSP and requests keep a reference to their
- * context.
- */
-int i915_switch_context(struct drm_i915_gem_request *rq)
-{
-	struct intel_engine_cs *engine = rq->engine;
-	struct i915_gem_context *to = rq->ctx;
-	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
-	struct i915_gem_context *saved_ctx = engine->legacy_active_context;
-	struct i915_hw_ppgtt *saved_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 (ppgtt != saved_mm ||
-	    (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) {
-		trace_switch_mm(engine, to);
-		ret = ppgtt->switch_mm(ppgtt, rq);
-		if (ret)
-			goto err;
-
-		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
-		engine->legacy_active_ppgtt = ppgtt;
-		hw_flags = MI_FORCE_RESTORE;
-	}
-
-	if (to->engine[engine->id].state &&
-	    (to != saved_ctx || hw_flags & MI_FORCE_RESTORE)) {
-		GEM_BUG_ON(engine->id != RCS);
-
-		/*
-		 * The kernel context(s) is treated as pure scratch and is not
-		 * expected to retain any state (as we sacrifice it during
-		 * suspend and on resume it may be corrupted). This is ok,
-		 * as nothing actually executes using the kernel context; it
-		 * is purely used for flushing user contexts.
-		 */
-		if (i915_gem_context_is_kernel(to))
-			hw_flags = MI_RESTORE_INHIBIT;
-
-		ret = mi_set_context(rq, hw_flags);
-		if (ret)
-			goto err_mm;
-
-		engine->legacy_active_context = to;
-	}
-
-	if (to->remap_slice) {
-		for (i = 0; i < MAX_L3_SLICES; i++) {
-			if (!(to->remap_slice & BIT(i)))
-				continue;
-
-			ret = remap_l3(rq, i);
-			if (ret)
-				goto err_ctx;
-		}
-
-		to->remap_slice = 0;
-	}
-
-	return 0;
-
-err_ctx:
-	engine->legacy_active_context = saved_ctx;
-err_mm:
-	engine->legacy_active_ppgtt = saved_mm;
-err:
-	return ret;
-}
-
 static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
 {
 	struct i915_gem_timeline *timeline;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index a904b0353bec..deb3cc7e08a8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1385,6 +1385,189 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv)
 		intel_ring_reset(engine->buffer, 0);
 }
 
+static inline int mi_set_context(struct drm_i915_gem_request *rq, u32 flags)
+{
+	struct drm_i915_private *i915 = rq->i915;
+	struct intel_engine_cs *engine = rq->engine;
+	enum intel_engine_id id;
+	const int num_rings =
+		/* Use an extended w/a on gen7 if signalling from other rings */
+		(HAS_LEGACY_SEMAPHORES(i915) && IS_GEN7(i915)) ?
+		INTEL_INFO(i915)->num_rings - 1 :
+		0;
+	int len;
+	u32 *cs;
+
+	flags |= MI_MM_SPACE_GTT;
+	if (IS_HASWELL(i915))
+		/* These flags are for resource streamer on HSW+ */
+		flags |= HSW_MI_RS_SAVE_STATE_EN | HSW_MI_RS_RESTORE_STATE_EN;
+	else
+		flags |= MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN;
+
+	len = 4;
+	if (IS_GEN7(i915))
+		len += 2 + (num_rings ? 4*num_rings + 6 : 0);
+
+	cs = intel_ring_begin(rq, len);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */
+	if (IS_GEN7(i915)) {
+		*cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
+		if (num_rings) {
+			struct intel_engine_cs *signaller;
+
+			*cs++ = MI_LOAD_REGISTER_IMM(num_rings);
+			for_each_engine(signaller, i915, id) {
+				if (signaller == engine)
+					continue;
+
+				*cs++ = i915_mmio_reg_offset(
+					   RING_PSMI_CTL(signaller->mmio_base));
+				*cs++ = _MASKED_BIT_ENABLE(
+						GEN6_PSMI_SLEEP_MSG_DISABLE);
+			}
+		}
+	}
+
+	*cs++ = MI_NOOP;
+	*cs++ = MI_SET_CONTEXT;
+	*cs++ = i915_ggtt_offset(rq->ctx->engine[RCS].state) | flags;
+	/*
+	 * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP
+	 * WaMiSetContext_Hang:snb,ivb,vlv
+	 */
+	*cs++ = MI_NOOP;
+
+	if (IS_GEN7(i915)) {
+		if (num_rings) {
+			struct intel_engine_cs *signaller;
+			i915_reg_t last_reg = {}; /* keep gcc quiet */
+
+			*cs++ = MI_LOAD_REGISTER_IMM(num_rings);
+			for_each_engine(signaller, i915, id) {
+				if (signaller == engine)
+					continue;
+
+				last_reg = RING_PSMI_CTL(signaller->mmio_base);
+				*cs++ = i915_mmio_reg_offset(last_reg);
+				*cs++ = _MASKED_BIT_DISABLE(
+						GEN6_PSMI_SLEEP_MSG_DISABLE);
+			}
+
+			/* Insert a delay before the next switch! */
+			*cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
+			*cs++ = i915_mmio_reg_offset(last_reg);
+			*cs++ = i915_ggtt_offset(engine->scratch);
+			*cs++ = MI_NOOP;
+		}
+		*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
+	}
+
+	intel_ring_advance(rq, cs);
+
+	return 0;
+}
+
+static int remap_l3(struct drm_i915_gem_request *rq, int slice)
+{
+	u32 *cs, *remap_info = rq->i915->l3_parity.remap_info[slice];
+	int i;
+
+	if (!remap_info)
+		return 0;
+
+	cs = intel_ring_begin(rq, GEN7_L3LOG_SIZE/4 * 2 + 2);
+	if (IS_ERR(cs))
+		return PTR_ERR(cs);
+
+	/*
+	 * Note: We do not worry about the concurrent register cacheline hang
+	 * here because no other code should access these registers other than
+	 * at initialization time.
+	 */
+	*cs++ = MI_LOAD_REGISTER_IMM(GEN7_L3LOG_SIZE/4);
+	for (i = 0; i < GEN7_L3LOG_SIZE/4; i++) {
+		*cs++ = i915_mmio_reg_offset(GEN7_L3LOG(slice, i));
+		*cs++ = remap_info[i];
+	}
+	*cs++ = MI_NOOP;
+	intel_ring_advance(rq, cs);
+
+	return 0;
+}
+
+static int switch_context(struct drm_i915_gem_request *rq)
+{
+	struct intel_engine_cs *engine = rq->engine;
+	struct i915_gem_context *to = rq->ctx;
+	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
+	struct i915_gem_context *saved_ctx = engine->legacy_active_context;
+	struct i915_hw_ppgtt *saved_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 (ppgtt != saved_mm ||
+	    (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) {
+		trace_switch_mm(engine, to);
+		ret = ppgtt->switch_mm(ppgtt, rq);
+		if (ret)
+			goto err;
+
+		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
+		engine->legacy_active_ppgtt = ppgtt;
+		hw_flags = MI_FORCE_RESTORE;
+	}
+
+	if (to->engine[engine->id].state &&
+	    (to != saved_ctx || hw_flags & MI_FORCE_RESTORE)) {
+		GEM_BUG_ON(engine->id != RCS);
+
+		/*
+		 * The kernel context(s) is treated as pure scratch and is not
+		 * expected to retain any state (as we sacrifice it during
+		 * suspend and on resume it may be corrupted). This is ok,
+		 * as nothing actually executes using the kernel context; it
+		 * is purely used for flushing user contexts.
+		 */
+		if (i915_gem_context_is_kernel(to))
+			hw_flags = MI_RESTORE_INHIBIT;
+
+		ret = mi_set_context(rq, hw_flags);
+		if (ret)
+			goto err_mm;
+
+		engine->legacy_active_context = to;
+	}
+
+	if (to->remap_slice) {
+		for (i = 0; i < MAX_L3_SLICES; i++) {
+			if (!(to->remap_slice & BIT(i)))
+				continue;
+
+			ret = remap_l3(rq, i);
+			if (ret)
+				goto err_ctx;
+		}
+
+		to->remap_slice = 0;
+	}
+
+	return 0;
+
+err_ctx:
+	engine->legacy_active_context = saved_ctx;
+err_mm:
+	engine->legacy_active_ppgtt = saved_mm;
+err:
+	return ret;
+}
+
 static int ring_request_alloc(struct drm_i915_gem_request *request)
 {
 	int ret;
@@ -1401,7 +1584,7 @@ static int ring_request_alloc(struct drm_i915_gem_request *request)
 	if (ret)
 		return ret;
 
-	ret = i915_switch_context(request);
+	ret = switch_context(request);
 	if (ret)
 		return ret;
 
-- 
2.15.0

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

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

* ✗ Fi.CI.BAT: warning for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
  2017-11-21  9:33 ` [PATCH 2/2] drm/i915: Move mi_set_context() into the legacy ringbuffer submission Chris Wilson
@ 2017-11-21  9:54 ` Patchwork
  2017-11-21 11:14 ` ✗ Fi.CI.BAT: failure " Patchwork
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2017-11-21  9:54 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
URL   : https://patchwork.freedesktop.org/series/34146/
State : warning

== Summary ==

Series 34146v1 series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
https://patchwork.freedesktop.org/api/1.0/series/34146/revisions/1/mbox/

Test gem_exec_reloc:
        Subgroup basic-write-cpu-active:
                fail       -> PASS       (fi-gdg-551)
Test kms_cursor_legacy:
        Subgroup basic-flip-before-cursor-varying-size:
                skip       -> PASS       (fi-hsw-4770r)
Test kms_flip:
        Subgroup basic-flip-vs-modeset:
                pass       -> SKIP       (fi-hsw-4770r)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713

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

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:446s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:454s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:381s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:543s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:282s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:503s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:513s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:499s
fi-byt-n2820     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:489s
fi-cfl-s2        total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:603s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:435s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:264s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:544s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:430s
fi-hsw-4770r     total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:418s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:426s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:479s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:468s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:488s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:532s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:476s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:539s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:577s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:459s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:540s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:563s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:524s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:497s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:463s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:558s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:419s
Blacklisted hosts:
fi-glk-dsi       total:25   pass:15   dwarn:0   dfail:0   fail:0   skip:9  

ee3fc3c956f817479cfe2bac3cc2a72112dbdec1 drm-tip: 2017y-11m-21d-09h-02m-11s UTC integration manifest
f0272d94d761 drm/i915: Move mi_set_context() into the legacy ringbuffer submission
e94958013ae4 drm/i915: Unwind incomplete legacy context switches

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7211/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: failure for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
  2017-11-21  9:33 ` [PATCH 2/2] drm/i915: Move mi_set_context() into the legacy ringbuffer submission Chris Wilson
  2017-11-21  9:54 ` ✗ Fi.CI.BAT: warning for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches Patchwork
@ 2017-11-21 11:14 ` Patchwork
  2017-11-21 12:47 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2017-11-21 11:14 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
URL   : https://patchwork.freedesktop.org/series/34146/
State : failure

== Summary ==

Series 34146v1 series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
https://patchwork.freedesktop.org/api/1.0/series/34146/revisions/1/mbox/

Test gem_exec_reloc:
        Subgroup basic-write-cpu-active:
                fail       -> PASS       (fi-gdg-551) fdo#102582
Test kms_cursor_legacy:
        Subgroup basic-flip-before-cursor-varying-size:
                skip       -> PASS       (fi-hsw-4770r)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713
Test drv_module_reload:
        Subgroup basic-reload-inject:
                pass       -> INCOMPLETE (fi-bwr-2160)

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

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:446s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:461s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:377s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:540s
fi-bwr-2160      total:288  pass:182  dwarn:0   dfail:0   fail:0   skip:105
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:506s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:505s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:497s
fi-byt-n2820     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:490s
fi-cfl-s2        total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:608s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:432s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:264s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:540s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:430s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:446s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:427s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:480s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:463s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:481s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:528s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:475s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:533s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:577s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:461s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:547s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:569s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:518s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:492s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:460s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:558s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:416s
Blacklisted hosts:
fi-glk-dsi       total:160  pass:136  dwarn:0   dfail:0   fail:1   skip:22 

ee3fc3c956f817479cfe2bac3cc2a72112dbdec1 drm-tip: 2017y-11m-21d-09h-02m-11s UTC integration manifest
1b7a5036acd0 drm/i915: Move mi_set_context() into the legacy ringbuffer submission
a11ad54c4cfc drm/i915: Unwind incomplete legacy context switches

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7214/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.BAT: success for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
                   ` (2 preceding siblings ...)
  2017-11-21 11:14 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2017-11-21 12:47 ` Patchwork
  2017-11-21 13:26 ` ✗ Fi.CI.BAT: warning " Patchwork
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2017-11-21 12:47 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
URL   : https://patchwork.freedesktop.org/series/34146/
State : success

== Summary ==

Series 34146v1 series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
https://patchwork.freedesktop.org/api/1.0/series/34146/revisions/1/mbox/

Test chamelium:
        Subgroup dp-crc-fast:
                pass       -> FAIL       (fi-kbl-7500u) fdo#103163
Test gem_exec_reloc:
        Subgroup basic-write-cpu-active:
                fail       -> PASS       (fi-gdg-551) fdo#102582
Test kms_cursor_legacy:
        Subgroup basic-flip-before-cursor-varying-size:
                skip       -> PASS       (fi-hsw-4770r)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713

fdo#103163 https://bugs.freedesktop.org/show_bug.cgi?id=103163
fdo#102582 https://bugs.freedesktop.org/show_bug.cgi?id=102582
fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:449s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:458s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:380s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:540s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:277s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:502s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:504s
fi-byt-n2820     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:488s
fi-cfl-s2        total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:606s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:429s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:269s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:540s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:433s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:441s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:430s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:477s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:465s
fi-kbl-7500u     total:289  pass:263  dwarn:1   dfail:0   fail:1   skip:24  time:477s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:536s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:477s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:536s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:573s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:453s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:555s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:562s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:520s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:498s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:460s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:560s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:422s
Blacklisted hosts:
fi-glk-dsi       total:289  pass:155  dwarn:0   dfail:10  fail:2   skip:122 time:356s
fi-bxt-j4205 failed to collect. IGT log at Patchwork_7218/fi-bxt-j4205/igt.log

ee3fc3c956f817479cfe2bac3cc2a72112dbdec1 drm-tip: 2017y-11m-21d-09h-02m-11s UTC integration manifest
43949a4edc66 drm/i915: Move mi_set_context() into the legacy ringbuffer submission
c15cd62ef890 drm/i915: Unwind incomplete legacy context switches

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7218/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: warning for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
                   ` (3 preceding siblings ...)
  2017-11-21 12:47 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2017-11-21 13:26 ` Patchwork
  2017-11-21 14:15 ` ✓ Fi.CI.IGT: success " Patchwork
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2017-11-21 13:26 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
URL   : https://patchwork.freedesktop.org/series/34146/
State : warning

== Summary ==

Series 34146v1 series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
https://patchwork.freedesktop.org/api/1.0/series/34146/revisions/1/mbox/

Test chamelium:
        Subgroup dp-crc-fast:
                pass       -> FAIL       (fi-kbl-7500u) fdo#103163
        Subgroup common-hpd-after-suspend:
                dmesg-warn -> PASS       (fi-kbl-7500u) fdo#102505
Test gem_exec_reloc:
        Subgroup basic-write-cpu-active:
                fail       -> PASS       (fi-gdg-551) fdo#102582
Test kms_cursor_legacy:
        Subgroup basic-flip-before-cursor-legacy:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup basic-flip-before-cursor-varying-size:
                skip       -> PASS       (fi-hsw-4770r)
Test kms_pipe_crc_basic:
        Subgroup read-crc-pipe-c-frame-sequence:
                pass       -> SKIP       (fi-hsw-4770r)
        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713

fdo#103163 https://bugs.freedesktop.org/show_bug.cgi?id=103163
fdo#102505 https://bugs.freedesktop.org/show_bug.cgi?id=102505
fdo#102582 https://bugs.freedesktop.org/show_bug.cgi?id=102582
fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:443s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:450s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:378s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:545s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:278s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:507s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:510s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:497s
fi-byt-n2820     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:486s
fi-cfl-s2        total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:612s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:429s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:266s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:536s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:432s
fi-hsw-4770r     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:440s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:430s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:485s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:461s
fi-kbl-7500u     total:289  pass:264  dwarn:0   dfail:0   fail:1   skip:24  time:477s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:525s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:473s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:534s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:576s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:457s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:541s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:563s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:519s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:491s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:465s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:563s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:427s
Blacklisted hosts:
fi-glk-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:502s

ee3fc3c956f817479cfe2bac3cc2a72112dbdec1 drm-tip: 2017y-11m-21d-09h-02m-11s UTC integration manifest
e0ea8dcb7ac1 drm/i915: Move mi_set_context() into the legacy ringbuffer submission
ad5777abf290 drm/i915: Unwind incomplete legacy context switches

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7220/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.IGT: success for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
                   ` (4 preceding siblings ...)
  2017-11-21 13:26 ` ✗ Fi.CI.BAT: warning " Patchwork
@ 2017-11-21 14:15 ` Patchwork
  2017-11-21 16:25 ` [PATCH 1/2] " Mika Kuoppala
  2017-11-23 13:48 ` Mika Kuoppala
  7 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2017-11-21 14:15 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915: Unwind incomplete legacy context switches
URL   : https://patchwork.freedesktop.org/series/34146/
State : success

== Summary ==

Warning: bzip CI_DRM_3367/shard-glkb3/results12.json.bz2 wasn't in correct JSON format
Test kms_flip:
        Subgroup dpms-vs-vblank-race:
                pass       -> FAIL       (shard-hsw) fdo#103060
        Subgroup flip-vs-expired-vblank:
                fail       -> PASS       (shard-hsw) fdo#102887
Test kms_frontbuffer_tracking:
        Subgroup fbc-1p-offscren-pri-shrfb-draw-render:
                pass       -> FAIL       (shard-snb) fdo#101623
Test perf:
        Subgroup blocking:
                pass       -> FAIL       (shard-hsw) fdo#102252

fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060
fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887
fdo#101623 https://bugs.freedesktop.org/show_bug.cgi?id=101623
fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252

shard-hsw        total:2585 pass:1472 dwarn:2   dfail:1   fail:11  skip:1099 time:9546s
shard-snb        total:2585 pass:1256 dwarn:2   dfail:1   fail:13  skip:1313 time:7978s
Blacklisted hosts:
shard-apl        total:2565 pass:1601 dwarn:2   dfail:0   fail:23  skip:937 time:13220s
shard-kbl        total:2488 pass:1643 dwarn:8   dfail:3   fail:22  skip:809 time:9856s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7218/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
                   ` (5 preceding siblings ...)
  2017-11-21 14:15 ` ✓ Fi.CI.IGT: success " Patchwork
@ 2017-11-21 16:25 ` Mika Kuoppala
  2017-11-21 16:30   ` Chris Wilson
  2017-11-23 13:48 ` Mika Kuoppala
  7 siblings, 1 reply; 10+ messages in thread
From: Mika Kuoppala @ 2017-11-21 16:25 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

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

> The legacy context switch for ringbuffer submission is multistaged,
> where each of those stages may fail. However, we were updating global
> state after some stages, and so we had to force the incomplete request
> to be submitted because we could not unwind. Save the global state
> before performing the switches, and so enable us to unwind back to the
> previous global state should any phase fail. We then must cancel the
> request instead of submitting it should the construction fail.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_context.c | 168 ++++++++++----------------------
>  drivers/gpu/drm/i915/i915_gem_request.c |  18 ++--
>  drivers/gpu/drm/i915/intel_ringbuffer.c |   1 +
>  drivers/gpu/drm/i915/intel_ringbuffer.h |   1 +
>  4 files changed, 62 insertions(+), 126 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 6ca56e482d79..f63bec08cc85 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -507,6 +507,7 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
>  
>  	for_each_engine(engine, dev_priv, id) {
>  		engine->legacy_active_context = NULL;
> +		engine->legacy_active_ppgtt = NULL;
>  
>  		if (!engine->last_retired_context)
>  			continue;
> @@ -681,68 +682,48 @@ static int remap_l3(struct drm_i915_gem_request *req, int slice)
>  	return 0;
>  }
>  
> -static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt,
> -				   struct intel_engine_cs *engine,
> -				   struct i915_gem_context *to)
> -{
> -	if (to->remap_slice)
> -		return false;
> -
> -	if (ppgtt && (intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
> -		return false;
> -
> -	return to == engine->legacy_active_context;
> -}
> -
> -static bool
> -needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine)
> -{
> -	struct i915_gem_context *from = engine->legacy_active_context;
> -
> -	if (!ppgtt)
> -		return false;
> -
> -	/* Always load the ppgtt on first use */
> -	if (!from)
> -		return true;
> -
> -	/* Same context without new entries, skip */
> -	if ((!from->ppgtt || from->ppgtt == ppgtt) &&
> -	    !(intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
> -		return false;
> -
> -	if (engine->id != RCS)
> -		return true;
> -
> -	return true;
> -}
> -
> -static int do_rcs_switch(struct drm_i915_gem_request *req)
> +/**
> + * i915_switch_context() - perform a GPU context switch.
> + * @rq: request for which we'll execute the context switch
> + *
> + * The context life cycle is simple. The context refcount is incremented and
> + * decremented by 1 and create and destroy. If the context is in use by the GPU,

s/and/on

> + * it will have a refcount > 1. This allows us to destroy the context abstract
> + * object while letting the normal object tracking destroy the backing BO.
> + *
> + * This function should not be used in execlists mode.  Instead the context is
> + * switched by writing to the ELSP and requests keep a reference to their
> + * context.
> + */
> +int i915_switch_context(struct drm_i915_gem_request *rq)
>  {
> -	struct i915_gem_context *to = req->ctx;
> -	struct intel_engine_cs *engine = req->engine;
> -	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
> -	struct i915_gem_context *from = engine->legacy_active_context;
> -	u32 hw_flags;
> +	struct intel_engine_cs *engine = rq->engine;
> +	struct i915_gem_context *to = rq->ctx;
> +	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
> +	struct i915_gem_context *saved_ctx = engine->legacy_active_context;
> +	struct i915_hw_ppgtt *saved_mm = engine->legacy_active_ppgtt;

saved as in context of this function or saved as in saved by hardware?
Just trying to get behind the naming here.

I am not in bottom of this patch yet but at this point,

new_[mm|ctx] and current[mm|ctx] feel more natural.

> +	u32 hw_flags = 0;
>  	int ret, i;
>  
> -	GEM_BUG_ON(engine->id != RCS);
> -
> -	if (skip_rcs_switch(ppgtt, engine, to))
> -		return 0;
> +	lockdep_assert_held(&rq->i915->drm.struct_mutex);
> +	GEM_BUG_ON(HAS_EXECLISTS(rq->i915));
>  
> -	if (needs_pd_load_pre(ppgtt, engine)) {
> -		/* Older GENs and non render rings still want the load first,
> -		 * "PP_DCLV followed by PP_DIR_BASE register through Load
> -		 * Register Immediate commands in Ring Buffer before submitting
> -		 * a context."*/
> +	if (ppgtt != saved_mm ||
> +	    (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) {
>  		trace_switch_mm(engine, to);
> -		ret = ppgtt->switch_mm(ppgtt, req);
> +		ret = ppgtt->switch_mm(ppgtt, rq);
>  		if (ret)
> -			return ret;
> +			goto err;
> +
> +		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
> +		engine->legacy_active_ppgtt = ppgtt;
> +		hw_flags = MI_FORCE_RESTORE;
>  	}
>  
> -	if (i915_gem_context_is_kernel(to))
> +	if (to->engine[engine->id].state &&
> +	    (to != saved_ctx || hw_flags & MI_FORCE_RESTORE)) {
> +		GEM_BUG_ON(engine->id != RCS);
> +
>  		/*
>  		 * The kernel context(s) is treated as pure scratch and is not
>  		 * expected to retain any state (as we sacrifice it during
> @@ -750,78 +731,37 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
>  		 * as nothing actually executes using the kernel context; it
>  		 * is purely used for flushing user contexts.
>  		 */
> -		hw_flags = MI_RESTORE_INHIBIT;
> -	else if (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)
> -		hw_flags = MI_FORCE_RESTORE;
> -	else
> -		hw_flags = 0;
> +		if (i915_gem_context_is_kernel(to))
> +			hw_flags = MI_RESTORE_INHIBIT;
>  
> -	if (to != from || (hw_flags & MI_FORCE_RESTORE)) {
> -		ret = mi_set_context(req, hw_flags);
> +		ret = mi_set_context(rq, hw_flags);
>  		if (ret)
> -			return ret;
> +			goto err_mm;
>  
>  		engine->legacy_active_context = to;
>  	}
>  
> -	if (ppgtt)
> -		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
> -
> -	for (i = 0; i < MAX_L3_SLICES; i++) {
> -		if (!(to->remap_slice & (1<<i)))
> -			continue;
> -
> -		ret = remap_l3(req, i);
> -		if (ret)
> -			return ret;
> -
> -		to->remap_slice &= ~(1<<i);
> -	}
> -
> -	return 0;
> -}
> -
> -/**
> - * i915_switch_context() - perform a GPU context switch.
> - * @req: request for which we'll execute the context switch
> - *
> - * The context life cycle is simple. The context refcount is incremented and
> - * decremented by 1 and create and destroy. If the context is in use by the GPU,
> - * it will have a refcount > 1. This allows us to destroy the context abstract
> - * object while letting the normal object tracking destroy the backing BO.
> - *
> - * This function should not be used in execlists mode.  Instead the context is
> - * switched by writing to the ELSP and requests keep a reference to their
> - * context.
> - */
> -int i915_switch_context(struct drm_i915_gem_request *req)
> -{
> -	struct intel_engine_cs *engine = req->engine;
> -
> -	lockdep_assert_held(&req->i915->drm.struct_mutex);
> -	GEM_BUG_ON(HAS_EXECLISTS(req->i915));
> +	if (to->remap_slice) {
> +		for (i = 0; i < MAX_L3_SLICES; i++) {
> +			if (!(to->remap_slice & BIT(i)))
> +				continue;
>  
> -	if (!req->ctx->engine[engine->id].state) {
> -		struct i915_gem_context *to = req->ctx;
> -		struct i915_hw_ppgtt *ppgtt =
> -			to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
> -
> -		if (needs_pd_load_pre(ppgtt, engine)) {
> -			int ret;
> -
> -			trace_switch_mm(engine, to);
> -			ret = ppgtt->switch_mm(ppgtt, req);
> +			ret = remap_l3(rq, i);
>  			if (ret)
> -				return ret;
> -
> -			ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
> +				goto err_ctx;
>  		}
>  
> -		engine->legacy_active_context = to;
> -		return 0;
> +		to->remap_slice = 0;

Because we have unwind we can just remap again everything if error
happens?

-Mika

>  	}
>  
> -	return do_rcs_switch(req);
> +	return 0;
> +
> +err_ctx:
> +	engine->legacy_active_context = saved_ctx;
> +err_mm:
> +	engine->legacy_active_ppgtt = saved_mm;
> +err:
> +	return ret;
>  }
>  
>  static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index 86e2346357cf..2749e4735563 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -718,25 +718,19 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>  	/* Unconditionally invalidate GPU caches and TLBs. */
>  	ret = engine->emit_flush(req, EMIT_INVALIDATE);
>  	if (ret)
> -		goto err_ctx;
> +		goto err_unwind;
>  
>  	ret = engine->request_alloc(req);
> -	if (ret) {
> -		/*
> -		 * Past the point-of-no-return. Since we may have updated
> -		 * global state after partially completing the request alloc,
> -		 * we need to commit any commands so far emitted in the
> -		 * request to the HW.
> -		 */
> -		__i915_add_request(req, false);
> -		return ERR_PTR(ret);
> -	}
> +	if (ret)
> +		goto err_unwind;
>  
>  	/* Check that we didn't interrupt ourselves with a new request */
>  	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
>  	return req;
>  
> -err_ctx:
> +err_unwind:
> +	req->ring->emit = req->head;
> +
>  	/* Make sure we didn't add ourselves to external state before freeing */
>  	GEM_BUG_ON(!list_empty(&req->active_list));
>  	GEM_BUG_ON(!list_empty(&req->priotree.signalers_list));
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index bfa11a84e476..a904b0353bec 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -591,6 +591,7 @@ static void reset_ring_common(struct intel_engine_cs *engine,
>  			request->ring->head = request->postfix;
>  	} else {
>  		engine->legacy_active_context = NULL;
> +		engine->legacy_active_ppgtt = NULL;
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index d16e32adf19a..cbc9c36f675e 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -494,6 +494,7 @@ struct intel_engine_cs {
>  	 * 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.15.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21 16:25 ` [PATCH 1/2] " Mika Kuoppala
@ 2017-11-21 16:30   ` Chris Wilson
  0 siblings, 0 replies; 10+ messages in thread
From: Chris Wilson @ 2017-11-21 16:30 UTC (permalink / raw)
  To: Mika Kuoppala, intel-gfx

Quoting Mika Kuoppala (2017-11-21 16:25:23)
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > The legacy context switch for ringbuffer submission is multistaged,
> > where each of those stages may fail. However, we were updating global
> > state after some stages, and so we had to force the incomplete request
> > to be submitted because we could not unwind. Save the global state
> > before performing the switches, and so enable us to unwind back to the
> > previous global state should any phase fail. We then must cancel the
> > request instead of submitting it should the construction fail.
> >
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> > ---
> > -static int do_rcs_switch(struct drm_i915_gem_request *req)
> > +/**
> > + * i915_switch_context() - perform a GPU context switch.
> > + * @rq: request for which we'll execute the context switch
> > + *
> > + * The context life cycle is simple. The context refcount is incremented and
> > + * decremented by 1 and create and destroy. If the context is in use by the GPU,
> 
> s/and/on
> 
> > + * it will have a refcount > 1. This allows us to destroy the context abstract
> > + * object while letting the normal object tracking destroy the backing BO.
> > + *
> > + * This function should not be used in execlists mode.  Instead the context is
> > + * switched by writing to the ELSP and requests keep a reference to their
> > + * context.
> > + */
> > +int i915_switch_context(struct drm_i915_gem_request *rq)
> >  {
> > -     struct i915_gem_context *to = req->ctx;
> > -     struct intel_engine_cs *engine = req->engine;
> > -     struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
> > -     struct i915_gem_context *from = engine->legacy_active_context;
> > -     u32 hw_flags;
> > +     struct intel_engine_cs *engine = rq->engine;
> > +     struct i915_gem_context *to = rq->ctx;
> > +     struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
> > +     struct i915_gem_context *saved_ctx = engine->legacy_active_context;
> > +     struct i915_hw_ppgtt *saved_mm = engine->legacy_active_ppgtt;
> 
> saved as in context of this function or saved as in saved by hardware?
> Just trying to get behind the naming here.

saved on stack.

The naming we've used elsewhere (ye olde save and restore across
suspend, around setcrtc etc).

> 
> I am not in bottom of this patch yet but at this point,
> 
> new_[mm|ctx] and current[mm|ctx] feel more natural.

[snip]
 
> > -             engine->legacy_active_context = to;
> > -             return 0;
> > +             to->remap_slice = 0;
> 
> Because we have unwind we can just remap again everything if error
> happens?

Right. Now since we cancel the request, the changes up to this point do
not exist on error, so we revert back to the previous state.

(Note this still imposes an order that needs magic if we switch to
virtual ringbuffers and reordering...)
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches
  2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
                   ` (6 preceding siblings ...)
  2017-11-21 16:25 ` [PATCH 1/2] " Mika Kuoppala
@ 2017-11-23 13:48 ` Mika Kuoppala
  7 siblings, 0 replies; 10+ messages in thread
From: Mika Kuoppala @ 2017-11-23 13:48 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

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

> The legacy context switch for ringbuffer submission is multistaged,
> where each of those stages may fail. However, we were updating global
> state after some stages, and so we had to force the incomplete request
> to be submitted because we could not unwind. Save the global state
> before performing the switches, and so enable us to unwind back to the
> previous global state should any phase fail. We then must cancel the
> request instead of submitting it should the construction fail.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>

Apart from the naming and the single typo, it seems
to do what it advertizes and cleans up the logic
considerably.

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

> ---
>  drivers/gpu/drm/i915/i915_gem_context.c | 168 ++++++++++----------------------
>  drivers/gpu/drm/i915/i915_gem_request.c |  18 ++--
>  drivers/gpu/drm/i915/intel_ringbuffer.c |   1 +
>  drivers/gpu/drm/i915/intel_ringbuffer.h |   1 +
>  4 files changed, 62 insertions(+), 126 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 6ca56e482d79..f63bec08cc85 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -507,6 +507,7 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
>  
>  	for_each_engine(engine, dev_priv, id) {
>  		engine->legacy_active_context = NULL;
> +		engine->legacy_active_ppgtt = NULL;
>  
>  		if (!engine->last_retired_context)
>  			continue;
> @@ -681,68 +682,48 @@ static int remap_l3(struct drm_i915_gem_request *req, int slice)
>  	return 0;
>  }
>  
> -static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt,
> -				   struct intel_engine_cs *engine,
> -				   struct i915_gem_context *to)
> -{
> -	if (to->remap_slice)
> -		return false;
> -
> -	if (ppgtt && (intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
> -		return false;
> -
> -	return to == engine->legacy_active_context;
> -}
> -
> -static bool
> -needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine)
> -{
> -	struct i915_gem_context *from = engine->legacy_active_context;
> -
> -	if (!ppgtt)
> -		return false;
> -
> -	/* Always load the ppgtt on first use */
> -	if (!from)
> -		return true;
> -
> -	/* Same context without new entries, skip */
> -	if ((!from->ppgtt || from->ppgtt == ppgtt) &&
> -	    !(intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
> -		return false;
> -
> -	if (engine->id != RCS)
> -		return true;
> -
> -	return true;
> -}
> -
> -static int do_rcs_switch(struct drm_i915_gem_request *req)
> +/**
> + * i915_switch_context() - perform a GPU context switch.
> + * @rq: request for which we'll execute the context switch
> + *
> + * The context life cycle is simple. The context refcount is incremented and
> + * decremented by 1 and create and destroy. If the context is in use by the GPU,
> + * it will have a refcount > 1. This allows us to destroy the context abstract
> + * object while letting the normal object tracking destroy the backing BO.
> + *
> + * This function should not be used in execlists mode.  Instead the context is
> + * switched by writing to the ELSP and requests keep a reference to their
> + * context.
> + */
> +int i915_switch_context(struct drm_i915_gem_request *rq)
>  {
> -	struct i915_gem_context *to = req->ctx;
> -	struct intel_engine_cs *engine = req->engine;
> -	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
> -	struct i915_gem_context *from = engine->legacy_active_context;
> -	u32 hw_flags;
> +	struct intel_engine_cs *engine = rq->engine;
> +	struct i915_gem_context *to = rq->ctx;
> +	struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: rq->i915->mm.aliasing_ppgtt;
> +	struct i915_gem_context *saved_ctx = engine->legacy_active_context;
> +	struct i915_hw_ppgtt *saved_mm = engine->legacy_active_ppgtt;
> +	u32 hw_flags = 0;
>  	int ret, i;
>  
> -	GEM_BUG_ON(engine->id != RCS);
> -
> -	if (skip_rcs_switch(ppgtt, engine, to))
> -		return 0;
> +	lockdep_assert_held(&rq->i915->drm.struct_mutex);
> +	GEM_BUG_ON(HAS_EXECLISTS(rq->i915));
>  
> -	if (needs_pd_load_pre(ppgtt, engine)) {
> -		/* Older GENs and non render rings still want the load first,
> -		 * "PP_DCLV followed by PP_DIR_BASE register through Load
> -		 * Register Immediate commands in Ring Buffer before submitting
> -		 * a context."*/
> +	if (ppgtt != saved_mm ||
> +	    (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) {
>  		trace_switch_mm(engine, to);
> -		ret = ppgtt->switch_mm(ppgtt, req);
> +		ret = ppgtt->switch_mm(ppgtt, rq);
>  		if (ret)
> -			return ret;
> +			goto err;
> +
> +		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
> +		engine->legacy_active_ppgtt = ppgtt;
> +		hw_flags = MI_FORCE_RESTORE;
>  	}
>  
> -	if (i915_gem_context_is_kernel(to))
> +	if (to->engine[engine->id].state &&
> +	    (to != saved_ctx || hw_flags & MI_FORCE_RESTORE)) {
> +		GEM_BUG_ON(engine->id != RCS);
> +
>  		/*
>  		 * The kernel context(s) is treated as pure scratch and is not
>  		 * expected to retain any state (as we sacrifice it during
> @@ -750,78 +731,37 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
>  		 * as nothing actually executes using the kernel context; it
>  		 * is purely used for flushing user contexts.
>  		 */
> -		hw_flags = MI_RESTORE_INHIBIT;
> -	else if (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings)
> -		hw_flags = MI_FORCE_RESTORE;
> -	else
> -		hw_flags = 0;
> +		if (i915_gem_context_is_kernel(to))
> +			hw_flags = MI_RESTORE_INHIBIT;
>  
> -	if (to != from || (hw_flags & MI_FORCE_RESTORE)) {
> -		ret = mi_set_context(req, hw_flags);
> +		ret = mi_set_context(rq, hw_flags);
>  		if (ret)
> -			return ret;
> +			goto err_mm;
>  
>  		engine->legacy_active_context = to;
>  	}
>  
> -	if (ppgtt)
> -		ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
> -
> -	for (i = 0; i < MAX_L3_SLICES; i++) {
> -		if (!(to->remap_slice & (1<<i)))
> -			continue;
> -
> -		ret = remap_l3(req, i);
> -		if (ret)
> -			return ret;
> -
> -		to->remap_slice &= ~(1<<i);
> -	}
> -
> -	return 0;
> -}
> -
> -/**
> - * i915_switch_context() - perform a GPU context switch.
> - * @req: request for which we'll execute the context switch
> - *
> - * The context life cycle is simple. The context refcount is incremented and
> - * decremented by 1 and create and destroy. If the context is in use by the GPU,
> - * it will have a refcount > 1. This allows us to destroy the context abstract
> - * object while letting the normal object tracking destroy the backing BO.
> - *
> - * This function should not be used in execlists mode.  Instead the context is
> - * switched by writing to the ELSP and requests keep a reference to their
> - * context.
> - */
> -int i915_switch_context(struct drm_i915_gem_request *req)
> -{
> -	struct intel_engine_cs *engine = req->engine;
> -
> -	lockdep_assert_held(&req->i915->drm.struct_mutex);
> -	GEM_BUG_ON(HAS_EXECLISTS(req->i915));
> +	if (to->remap_slice) {
> +		for (i = 0; i < MAX_L3_SLICES; i++) {
> +			if (!(to->remap_slice & BIT(i)))
> +				continue;
>  
> -	if (!req->ctx->engine[engine->id].state) {
> -		struct i915_gem_context *to = req->ctx;
> -		struct i915_hw_ppgtt *ppgtt =
> -			to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
> -
> -		if (needs_pd_load_pre(ppgtt, engine)) {
> -			int ret;
> -
> -			trace_switch_mm(engine, to);
> -			ret = ppgtt->switch_mm(ppgtt, req);
> +			ret = remap_l3(rq, i);
>  			if (ret)
> -				return ret;
> -
> -			ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
> +				goto err_ctx;
>  		}
>  
> -		engine->legacy_active_context = to;
> -		return 0;
> +		to->remap_slice = 0;
>  	}
>  
> -	return do_rcs_switch(req);
> +	return 0;
> +
> +err_ctx:
> +	engine->legacy_active_context = saved_ctx;
> +err_mm:
> +	engine->legacy_active_ppgtt = saved_mm;
> +err:
> +	return ret;
>  }
>  
>  static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index 86e2346357cf..2749e4735563 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -718,25 +718,19 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
>  	/* Unconditionally invalidate GPU caches and TLBs. */
>  	ret = engine->emit_flush(req, EMIT_INVALIDATE);
>  	if (ret)
> -		goto err_ctx;
> +		goto err_unwind;
>  
>  	ret = engine->request_alloc(req);
> -	if (ret) {
> -		/*
> -		 * Past the point-of-no-return. Since we may have updated
> -		 * global state after partially completing the request alloc,
> -		 * we need to commit any commands so far emitted in the
> -		 * request to the HW.
> -		 */
> -		__i915_add_request(req, false);
> -		return ERR_PTR(ret);
> -	}
> +	if (ret)
> +		goto err_unwind;
>  
>  	/* Check that we didn't interrupt ourselves with a new request */
>  	GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
>  	return req;
>  
> -err_ctx:
> +err_unwind:
> +	req->ring->emit = req->head;
> +
>  	/* Make sure we didn't add ourselves to external state before freeing */
>  	GEM_BUG_ON(!list_empty(&req->active_list));
>  	GEM_BUG_ON(!list_empty(&req->priotree.signalers_list));
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index bfa11a84e476..a904b0353bec 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -591,6 +591,7 @@ static void reset_ring_common(struct intel_engine_cs *engine,
>  			request->ring->head = request->postfix;
>  	} else {
>  		engine->legacy_active_context = NULL;
> +		engine->legacy_active_ppgtt = NULL;
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index d16e32adf19a..cbc9c36f675e 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -494,6 +494,7 @@ struct intel_engine_cs {
>  	 * 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.15.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-11-23 13:48 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-21  9:33 [PATCH 1/2] drm/i915: Unwind incomplete legacy context switches Chris Wilson
2017-11-21  9:33 ` [PATCH 2/2] drm/i915: Move mi_set_context() into the legacy ringbuffer submission Chris Wilson
2017-11-21  9:54 ` ✗ Fi.CI.BAT: warning for series starting with [1/2] drm/i915: Unwind incomplete legacy context switches Patchwork
2017-11-21 11:14 ` ✗ Fi.CI.BAT: failure " Patchwork
2017-11-21 12:47 ` ✓ Fi.CI.BAT: success " Patchwork
2017-11-21 13:26 ` ✗ Fi.CI.BAT: warning " Patchwork
2017-11-21 14:15 ` ✓ Fi.CI.IGT: success " Patchwork
2017-11-21 16:25 ` [PATCH 1/2] " Mika Kuoppala
2017-11-21 16:30   ` Chris Wilson
2017-11-23 13:48 ` Mika Kuoppala

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.