[PATCH 2/2] defaults2

Chris Wilson chris at chris-wilson.co.uk
Wed Nov 1 11:23:09 UTC 2017


---
 drivers/gpu/drm/i915/i915_gem.c         |  59 ++++++++++++-
 drivers/gpu/drm/i915/i915_gem_context.c |  10 +--
 drivers/gpu/drm/i915/i915_gem_context.h |   3 +
 drivers/gpu/drm/i915/intel_lrc.c        | 146 ++++----------------------------
 4 files changed, 83 insertions(+), 135 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e43688f77817..1e6a50237c40 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4974,6 +4974,56 @@ bool intel_sanitize_semaphores(struct drm_i915_private *dev_priv, int value)
 	return true;
 }
 
+static int __intel_engines_record_defaults(struct drm_i915_private *i915)
+{
+	struct i915_gem_context *ctx;
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	int err;
+
+	/*
+	 * As we reset the gpu during very early sanitisation, the current
+	 * register state on the GPU should reflect its defaults values.
+	 * We load a context onto the hw (with restore-inhibit), then switch
+	 * over to a second context to save that default register state. We
+	 * can then prime every new context with that state so they all start
+	 * from defaults.
+	 */
+
+	ctx = i915_gem_context_create_kernel(i915, 0);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	for_each_engine(engine, i915, id) {
+		struct drm_i915_gem_request *rq;
+
+		rq = i915_gem_request_alloc(engine, ctx);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			goto out_ctx;
+		}
+		i915_add_request(rq);
+	}
+
+	err = i915_gem_switch_to_kernel_context(i915);
+	if (err)
+		goto out_ctx;
+
+	err = i915_gem_wait_for_idle(i915, I915_WAIT_LOCKED);
+	if (err)
+		goto out_ctx;
+
+	for_each_engine(engine, i915, id) {
+		engine->default_state =
+			i915_gem_object_get(ctx->engine[id].state->obj);
+	}
+
+out_ctx:
+	i915_gem_context_set_closed(ctx);
+	i915_gem_context_put(ctx);
+	return err;
+}
+
 int i915_gem_init(struct drm_i915_private *dev_priv)
 {
 	int ret;
@@ -5024,6 +5074,14 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 		goto out_unlock;
 
 	ret = i915_gem_init_hw(dev_priv);
+	if (ret)
+		goto out_unlock;
+
+	ret = __intel_engines_record_defaults(dev_priv);
+	if (ret)
+		goto out_unlock;
+
+out_unlock:
 	if (ret == -EIO) {
 		/* Allow engine initialisation to fail by marking the GPU as
 		 * wedged. But we only want to do this where the GPU is angry,
@@ -5036,7 +5094,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 		ret = 0;
 	}
 
-out_unlock:
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 10affb35ac56..495524fb2065 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -343,7 +343,7 @@ static void __destroy_hw_context(struct i915_gem_context *ctx,
  * context state of the GPU for applications that don't utilize HW contexts, as
  * well as an idle case.
  */
-static struct i915_gem_context *
+struct i915_gem_context *
 i915_gem_create_context(struct drm_i915_private *dev_priv,
 			struct drm_i915_file_private *file_priv)
 {
@@ -418,8 +418,8 @@ i915_gem_context_create_gvt(struct drm_device *dev)
 	return ctx;
 }
 
-static struct i915_gem_context *
-create_kernel_context(struct drm_i915_private *i915, int prio)
+struct i915_gem_context *
+i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio)
 {
 	struct i915_gem_context *ctx;
 
@@ -473,7 +473,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
 	ida_init(&dev_priv->contexts.hw_ida);
 
 	/* lowest priority; idle task */
-	ctx = create_kernel_context(dev_priv, I915_PRIORITY_MIN);
+	ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_MIN);
 	if (IS_ERR(ctx)) {
 		DRM_ERROR("Failed to create default global context\n");
 		err = PTR_ERR(ctx);
@@ -487,7 +487,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
 	dev_priv->kernel_context = ctx;
 
 	/* highest priority; preempting task */
-	ctx = create_kernel_context(dev_priv, INT_MAX);
+	ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
 	if (IS_ERR(ctx)) {
 		DRM_ERROR("Failed to create default preempt context\n");
 		err = PTR_ERR(ctx);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 44688e22a5c2..fb482ec1351b 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -292,6 +292,9 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
 int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
 				       struct drm_file *file);
 
+struct i915_gem_context *
+i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio);
+
 static inline struct i915_gem_context *
 i915_gem_context_get(struct i915_gem_context *ctx)
 {
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 55bacca97de7..77b0fda88844 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1449,7 +1449,7 @@ static void enable_execlists(struct intel_engine_cs *engine)
 	POSTING_READ(RING_HWS_PGA(engine->mmio_base));
 }
 
-static int gen8_init_common_ring(struct intel_engine_cs *engine)
+static int init_xcs(struct intel_engine_cs *engine)
 {
 	struct drm_i915_private *dev_priv = engine->i915;
 	struct intel_engine_execlists * const execlists = &engine->execlists;
@@ -1489,12 +1489,17 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
 	return 0;
 }
 
-static int gen8_init_render_ring(struct intel_engine_cs *engine)
+static int init_hw(struct intel_engine_cs *engine)
+{
+	return init_xcs(engine);
+}
+
+static int gen8_init_rcs(struct intel_engine_cs *engine)
 {
 	struct drm_i915_private *dev_priv = engine->i915;
 	int ret;
 
-	ret = gen8_init_common_ring(engine);
+	ret = init_xcs(engine);
 	if (ret)
 		return ret;
 
@@ -1511,11 +1516,11 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
 	return init_workarounds_ring(engine);
 }
 
-static int gen9_init_render_ring(struct intel_engine_cs *engine)
+static int gen9_init_rcs(struct intel_engine_cs *engine)
 {
 	int ret;
 
-	ret = gen8_init_common_ring(engine);
+	ret = init_xcs(engine);
 	if (ret)
 		return ret;
 
@@ -1901,7 +1906,7 @@ static void
 logical_ring_default_vfuncs(struct intel_engine_cs *engine)
 {
 	/* Default vfuncs which can be overriden by each engine. */
-	engine->init_hw = gen8_init_common_ring;
+	engine->init_hw = init_hw;
 	engine->reset_hw = reset_common_ring;
 
 	engine->context_pin = execlists_context_pin;
@@ -1928,120 +1933,6 @@ logical_ring_default_irqs(struct intel_engine_cs *engine)
 	engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift;
 }
 
-static bool csb_idle(struct intel_engine_cs *engine)
-{
-	struct drm_i915_private *i915 = engine->i915;
-	u32 __iomem *status =
-		i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0));
-	u32 __iomem *ring =
-		i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine));
-	u32 head, tail;
-	bool idle = false;
-
-	head = ioread32(ring);
-	tail = GEN8_CSB_WRITE_PTR(head);
-	head = GEN8_CSB_READ_PTR(head);
-
-	if (head >= GEN8_CSB_ENTRIES || tail >= GEN8_CSB_ENTRIES)
-		return false;
-
-	while (head != tail) {
-		if (++head == GEN8_CSB_ENTRIES)
-			head = 0;
-
-		if (ioread32(status + 2 * head) & GEN8_CTX_STATUS_ACTIVE_IDLE)
-			idle = true;
-	}
-
-	iowrite32(_MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, head << 8), ring);
-
-	return idle;
-}
-
-static int lrc_record_defaults(struct intel_engine_cs *engine)
-{
-	struct drm_i915_private *i915 = engine->i915;
-	u32 __iomem *elsp =
-		i915->regs + i915_mmio_reg_offset(RING_ELSP(engine));
-	struct i915_gem_context *kctx = i915->kernel_context;
-	struct intel_context *ce = &kctx->engine[engine->id];
-	struct drm_i915_gem_object *obj;
-	struct i915_vma *vma;
-	u32 context_size;
-	void *vaddr;
-	u32 *regs;
-	u64 desc;
-	int err;
-
-	/*
-	 * As we reset the gpu during very early sanitisation, the current
-	 * register state on the GPU should reflect its defaults values.
-	 * We load a context onto the hw (with restore-inhibit), then switch
-	 * over to a second context to save that default register state. We
-	 * then prime every new context with that state so they all start
-	 * from defaults.
-	 */
-
-	intel_runtime_pm_get(i915);
-	intel_uncore_forcewake_get(i915, FORCEWAKE_ALL);
-
-	context_size = round_up(engine->context_size, I915_GTT_PAGE_SIZE);
-	obj = i915_gem_object_create(i915, context_size);
-	if (IS_ERR(obj)) {
-		err = PTR_ERR(obj);
-		goto out_rpm;
-	}
-
-	vma = i915_vma_instance(obj, &i915->ggtt.base, NULL);
-	if (IS_ERR(vma)) {
-		err = PTR_ERR(vma);
-		goto out_obj;
-	}
-
-	err = i915_vma_pin(vma, 0, GEN8_LR_CONTEXT_ALIGN, PIN_GLOBAL);
-	if (err)
-		goto out_obj;
-
-	vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
-	if (IS_ERR(vaddr)) {
-		err = PTR_ERR(vaddr);
-		goto out_vma;
-	}
-
-	regs = vaddr + PAGE_SIZE;
-	execlists_init_reg_state(regs, kctx, engine, ce->ring);
-	regs[CTX_CONTEXT_CONTROL+1] |=
-		_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
-
-	desc = kctx->desc_template;
-	desc |= i915_ggtt_offset(vma);
-	desc |= (u64)(MAX_CONTEXT_HW_ID - 1) << GEN8_CTX_ID_SHIFT;
-
-	/* ELSP is programmed backwards. 2nd context first, 1st context last. */
-	enable_execlists(engine);
-	elsp_write(ce->lrc_desc, elsp);
-	elsp_write(desc, elsp);
-
-	msleep(1);
-	if (!wait_for(csb_idle(engine), 1000)) {
-		obj->mm.dirty = true;
-		engine->default_state = i915_gem_object_get(obj);
-	} else {
-		err = -EIO;
-	}
-
-	i915_gem_object_unpin_map(obj);
-out_vma:
-	i915_vma_unpin(vma);
-out_obj:
-	i915_gem_object_put(obj);
-out_rpm:
-	intel_uncore_forcewake_put(i915, FORCEWAKE_ALL);
-	intel_runtime_pm_put(i915);
-
-	return err;
-}
-
 static void
 logical_ring_setup(struct intel_engine_cs *engine)
 {
@@ -2082,10 +1973,6 @@ static int logical_ring_init(struct intel_engine_cs *engine)
 	if (ret)
 		goto error;
 
-	ret = lrc_record_defaults(engine);
-	if (ret)
-		goto error;
-
 	return 0;
 
 error:
@@ -2105,9 +1992,9 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
 
 	/* Override some for render ring. */
 	if (INTEL_GEN(dev_priv) >= 9)
-		engine->init_hw = gen9_init_render_ring;
+		engine->init_hw = gen9_init_rcs;
 	else
-		engine->init_hw = gen8_init_render_ring;
+		engine->init_hw = gen8_init_rcs;
 	engine->init_context = gen8_init_rcs_context;
 	engine->emit_flush = gen8_emit_flush_render;
 	engine->emit_breadcrumb = gen8_emit_breadcrumb_rcs;
@@ -2330,13 +2217,14 @@ populate_lr_context(struct i915_gem_context *ctx,
 			return PTR_ERR(defaults);
 
 		memcpy(vaddr + LRC_HEADER_PAGES * PAGE_SIZE,
-		       defaults, engine->context_size);
+		       defaults + LRC_HEADER_PAGES * PAGE_SIZE,
+		       engine->context_size);
 		i915_gem_object_unpin_map(engine->default_state);
 	}
 
 	/* The second page of the context object contains some fields which must
 	 * be set up prior to the first execution. */
-	regs = vaddr + LRC_STATE_PN * PAGE_SIZE,
+	regs = vaddr + LRC_STATE_PN * PAGE_SIZE;
 	execlists_init_reg_state(regs, ctx, engine, ring);
 	if (!engine->default_state) {
 		regs[CTX_CONTEXT_CONTROL+1] |=
@@ -2394,7 +2282,7 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 
 	ce->ring = ring;
 	ce->state = vma;
-	ce->initialised |= engine->init_context == NULL;
+	ce->initialised |= engine->default_state || !engine->init_context;
 
 	return 0;
 
-- 
2.15.0.rc2



More information about the Intel-gfx-trybot mailing list