diff mbox

[RFC,3/8] drm/i915: Execlists to mark the HWSP upon preemption finished

Message ID 20180316183105.16027-4-jeff.mcgee@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

jeff.mcgee@intel.com March 16, 2018, 6:31 p.m. UTC
From: Jeff McGee <jeff.mcgee@intel.com>

In the next patch we are improving how we find the active request
on an engine with a pending preemption. We need to know if the
preemption has completed or not. This determination can be made
most robustly by having the preemption context write a preemption
finished indicator to the hardware status page.

This patch is required to support the force preemption feature.

Change-Id: I4123283aec02e21d13c7cb55f329cf3f553b5d2c
Signed-off-by: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c        | 27 ++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_ringbuffer.h | 14 +++++++++++++-
 2 files changed, 37 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 5f63d1d6a2d6..b2f838c484b0 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -512,19 +512,37 @@  static void port_assign(struct execlist_port *port,
 	port_set(port, port_pack(i915_gem_request_get(rq), port_count(port)));
 }
 
+#define PREEMPT_BREADCRUMB_DWORDS 0x8
 static void inject_preempt_context(struct intel_engine_cs *engine)
 {
 	struct intel_context *ce =
 		&engine->i915->preempt_context->engine[engine->id];
+	u32 *cs = ce->ring->vaddr + ce->ring->tail;
 	u32 __iomem *elsp =
 		engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine));
 	unsigned int n;
 
 	GEM_BUG_ON(engine->i915->preempt_context->hw_id != PREEMPT_ID);
-	GEM_BUG_ON(!IS_ALIGNED(ce->ring->size, WA_TAIL_BYTES));
+	GEM_BUG_ON(intel_engine_preempt_finished(engine));
 
-	memset(ce->ring->vaddr + ce->ring->tail, 0, WA_TAIL_BYTES);
-	ce->ring->tail += WA_TAIL_BYTES;
+	if (engine->id == RCS) {
+		cs = gen8_emit_ggtt_write_rcs(cs, I915_GEM_HWS_PREEMPT_FINISHED,
+				intel_hws_preempt_done_address(engine));
+	} else {
+		cs = gen8_emit_ggtt_write(cs, I915_GEM_HWS_PREEMPT_FINISHED,
+				intel_hws_preempt_done_address(engine));
+		*cs++ = MI_NOOP;
+		*cs++ = MI_NOOP;
+	}
+	*cs++ = MI_NOOP;
+	*cs++ = MI_NOOP;
+
+	GEM_BUG_ON(!IS_ALIGNED(ce->ring->size,
+			       PREEMPT_BREADCRUMB_DWORDS * sizeof(u32)));
+	GEM_BUG_ON((void *)cs - (ce->ring->vaddr + ce->ring->tail) !=
+		   PREEMPT_BREADCRUMB_DWORDS * sizeof(u32));
+
+	ce->ring->tail += PREEMPT_BREADCRUMB_DWORDS * sizeof(u32);
 	ce->ring->tail &= (ce->ring->size - 1);
 	ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail;
 
@@ -911,6 +929,8 @@  static void intel_lrc_irq_handler(unsigned long data)
 								EXECLISTS_ACTIVE_PREEMPT));
 				execlists_clear_active(execlists,
 						       EXECLISTS_ACTIVE_PREEMPT);
+				GEM_BUG_ON(!intel_engine_preempt_finished(engine));
+				intel_engine_clear_preempt(engine);
 				continue;
 			}
 
@@ -1507,6 +1527,7 @@  static int gen8_init_common_ring(struct intel_engine_cs *engine)
 
 	execlists->csb_head = -1;
 	execlists->active = 0;
+	intel_engine_clear_preempt(engine);
 
 	/* After a GPU reset, we may have requests to replay */
 	if (!i915_modparams.enable_guc_submission && execlists->first)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 5b9117b3cba4..25eb23bc06eb 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -625,11 +625,12 @@  intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 #define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
 #define I915_GEM_HWS_PREEMPT_INDEX	0x32
 #define I915_GEM_HWS_PREEMPT_ADDR (I915_GEM_HWS_PREEMPT_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
+#define I915_GEM_HWS_PREEMPT_FINISHED	1
 #define I915_GEM_HWS_PID_INDEX 0x40
 #define I915_GEM_HWS_PID_ADDR (I915_GEM_HWS_PID_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
 #define I915_GEM_HWS_CID_INDEX 0x48
 #define I915_GEM_HWS_CID_ADDR (I915_GEM_HWS_CID_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
-#define I915_GEM_HWS_SCRATCH_INDEX     0x50
+#define I915_GEM_HWS_SCRATCH_INDEX	0x58
 #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
 
 #define I915_HWS_CSB_BUF0_INDEX		0x10
@@ -749,6 +750,17 @@  static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine)
 	return intel_read_status_page(engine, I915_GEM_HWS_INDEX);
 }
 
+static inline bool intel_engine_preempt_finished(struct intel_engine_cs *engine)
+{
+	return (intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) ==
+		I915_GEM_HWS_PREEMPT_FINISHED);
+}
+
+static inline void intel_engine_clear_preempt(struct intel_engine_cs *engine)
+{
+	intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0);
+}
+
 static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine)
 {
 	/* We are only peeking at the tail of the submit queue (and not the