[CI 2/2] drm/i915: Add per ctx batchbuffer wa for timestamp
Mika Kuoppala
mika.kuoppala at linux.intel.com
Tue Apr 7 18:00:32 UTC 2020
Restoration of a previous timestamp can collide
with updating the timestamp, causing a value corruption.
Combat this issue by using context bb which will be
run after a context restoration process. Force fetch the
timestamp value from the context image.
References: HSDES#16010904313
Testcase: igt/i915_selftest/gt_lrc
Suggested-by: Joseph Koston <joseph.koston at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
---
drivers/gpu/drm/i915/gt/intel_context_types.h | 4 ++
drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 3 +-
drivers/gpu/drm/i915/gt/intel_lrc.c | 49 ++++++++++++++++++-
drivers/gpu/drm/i915/gt/intel_lrc_reg.h | 1 +
4 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 07cb83a0d017..93623d27b974 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -70,6 +70,10 @@ struct intel_context {
u32 *lrc_reg_state;
u64 lrc_desc;
+
+ u32 *ctx_bb;
+ u32 ctx_bb_offset;
+
u32 tag; /* cookie passed to HW to track this context on submission */
/* Time on GPU as tracked by the hw. */
diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index f04214a54f75..0c2adb4078a7 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -138,7 +138,7 @@
*/
#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*(x)-1)
/* Gen11+. addr = base + (ctx_restore ? offset & GENMASK(12,2) : offset) */
-#define MI_LRI_CS_MMIO (1<<19)
+#define MI_LRI_LRM_CS_MMIO (1<<19)
#define MI_LRI_FORCE_POSTED (1<<12)
#define MI_LOAD_REGISTER_IMM_MAX_REGS (126)
#define MI_STORE_REGISTER_MEM MI_INSTR(0x24, 1)
@@ -155,6 +155,7 @@
#define MI_FLUSH_DW_USE_PPGTT (0<<2)
#define MI_LOAD_REGISTER_MEM MI_INSTR(0x29, 1)
#define MI_LOAD_REGISTER_MEM_GEN8 MI_INSTR(0x29, 2)
+#define MI_LRM_ASYNC (1<<21)
#define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 1)
#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
#define MI_BATCH_NON_SECURE (1)
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 488ade93626f..a32458f98a1a 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -537,7 +537,7 @@ static void set_offsets(u32 *regs,
if (flags & POSTED)
*regs |= MI_LRI_FORCE_POSTED;
if (INTEL_GEN(engine->i915) >= 11)
- *regs |= MI_LRI_CS_MMIO;
+ *regs |= MI_LRI_LRM_CS_MMIO;
regs++;
GEM_BUG_ON(!count);
@@ -3142,6 +3142,40 @@ static void execlists_context_unpin(struct intel_context *ce)
i915_gem_object_unpin_map(ce->state->obj);
}
+static void
+gen12_setup_ctx_bb(const struct intel_context *ce)
+{
+ const u32 gaddr = i915_ggtt_offset(ce->state);
+ const u32 ggtt_timestamp_offset = gaddr +
+ + LRC_STATE_PN * PAGE_SIZE + CTX_TIMESTAMP * sizeof(u32);
+ const u32 ctx_timestamp_offset = i915_mmio_reg_offset(RING_CTX_TIMESTAMP(0));
+ const u32 cmd = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT | MI_LRI_LRM_CS_MMIO;
+ u32 *batch = ce->ctx_bb;
+ GEM_DEBUG_DECL(const u32 *batch_start = batch);
+
+ *batch++ = cmd | MI_LRM_ASYNC;
+ *batch++ = ctx_timestamp_offset;
+ *batch++ = ggtt_timestamp_offset;
+ *batch++ = 0;
+
+ *batch++ = cmd | MI_LRM_ASYNC;
+ *batch++ = ctx_timestamp_offset;
+ *batch++ = ggtt_timestamp_offset;
+ *batch++ = 0;
+
+ *batch++ = cmd;
+ *batch++ = ctx_timestamp_offset;
+ *batch++ = ggtt_timestamp_offset;
+ *batch++ = 0;
+
+ *batch++ = MI_BATCH_BUFFER_END;
+
+ GEM_DEBUG_BUG_ON(batch - batch_start > I915_GTT_PAGE_SIZE/sizeof(cmd));
+
+ ce->lrc_reg_state[GEN12_CTX_BB_PER_CTX_PTR] =
+ (gaddr + ce->ctx_bb_offset) | CTX_BB_PER_CTX_PTR_VALID;
+}
+
static void
__execlists_update_reg_state(const struct intel_context *ce,
const struct intel_engine_cs *engine,
@@ -3164,7 +3198,11 @@ __execlists_update_reg_state(const struct intel_context *ce,
intel_sseu_make_rpcs(engine->i915, &ce->sseu);
i915_oa_init_reg_state(ce, engine);
+
}
+
+ if (ce->ctx_bb)
+ gen12_setup_ctx_bb(ce);
}
static int
@@ -3184,6 +3222,10 @@ __execlists_context_pin(struct intel_context *ce,
ce->lrc_desc = lrc_descriptor(ce, engine) | CTX_DESC_FORCE_RESTORE;
ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
+
+ if (ce->ctx_bb_offset)
+ ce->ctx_bb = vaddr + ce->ctx_bb_offset;
+
__execlists_update_reg_state(ce, engine, ce->ring->tail);
return 0;
@@ -4844,6 +4886,11 @@ static int __execlists_context_alloc(struct intel_context *ce,
if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
context_size += I915_GTT_PAGE_SIZE; /* for redzone */
+ if (INTEL_GEN(engine->i915) == 12) {
+ ce->ctx_bb_offset = context_size;
+ context_size += PAGE_SIZE;
+ }
+
ctx_obj = i915_gem_object_create_shmem(engine->i915, context_size);
if (IS_ERR(ctx_obj))
return PTR_ERR(ctx_obj);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
index d39b72590e40..1364c1e31ebb 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h
@@ -32,6 +32,7 @@
/* GEN12+ Reg State Context */
#define GEN12_CTX_BB_PER_CTX_PTR (0x12 + 1)
+#define CTX_BB_PER_CTX_PTR_VALID BIT(0)
#define ASSIGN_CTX_PDP(ppgtt, reg_state, n) do { \
u32 *reg_state__ = (reg_state); \
--
2.17.1
More information about the Intel-gfx-trybot
mailing list