summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/gt/intel_lrc.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 3d5f3f7677bb..9fff4e02cee6 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -2342,6 +2342,13 @@ gen8_csb_parse(const struct intel_engine_execlists *execlists, const u32 *csb)
return *csb & (GEN8_CTX_STATUS_IDLE_ACTIVE | GEN8_CTX_STATUS_PREEMPTED);
}
+static inline void flush_hwsp(const struct i915_request *rq)
+{
+ mb();
+ clflush((void *)READ_ONCE(rq->hwsp_seqno));
+ mb();
+}
+
static void process_csb(struct intel_engine_cs *engine)
{
struct intel_engine_execlists * const execlists = &engine->execlists;
@@ -2418,8 +2425,6 @@ static void process_csb(struct intel_engine_cs *engine)
if (promote) {
struct i915_request * const *old = execlists->active;
- GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
-
ring_set_paused(engine, 0);
/* Point active to the new ELSP; prevent overwriting */
@@ -2432,6 +2437,7 @@ static void process_csb(struct intel_engine_cs *engine)
execlists_schedule_out(*old++);
/* switch pending to inflight */
+ GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
memcpy(execlists->inflight,
execlists->pending,
execlists_num_ports(execlists) *
@@ -2453,13 +2459,24 @@ static void process_csb(struct intel_engine_cs *engine)
* user interrupt and CSB is processed.
*/
if (GEM_SHOW_DEBUG() &&
- !i915_request_completed(*execlists->active) &&
- !reset_in_progress(execlists)) {
- struct i915_request *rq __maybe_unused =
- *execlists->active;
+ !i915_request_completed(*execlists->active)) {
+ struct i915_request *rq = *execlists->active;
const u32 *regs __maybe_unused =
rq->context->lrc_reg_state;
+ /*
+ * Flush the breadcrumb before crying foul.
+ *
+ * Since we have hit this on icl and seen the
+ * breadcrumb advance as we print out the debug
+ * info (so the problem corrected itself without
+ * lasting damage), and we know that icl suffers
+ * from missing global observation points in
+ * execlists, presume that affects even more
+ * coherency.
+ */
+ flush_hwsp(rq);
+
ENGINE_TRACE(engine,
"ring:{start:0x%08x, head:%04x, tail:%04x, ctl:%08x, mode:%08x}\n",
ENGINE_READ(engine, RING_START),
@@ -2480,7 +2497,10 @@ static void process_csb(struct intel_engine_cs *engine)
regs[CTX_RING_HEAD],
regs[CTX_RING_TAIL]);
- GEM_BUG_ON("context completed before request");
+ /* Still? Declare it caput! */
+ if (!i915_request_completed(rq) &&
+ !reset_in_progress(execlists))
+ GEM_BUG_ON("context completed before request");
}
execlists_schedule_out(*execlists->active++);