[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