drm/i915/gt: Perform an arbitration check before busywaiting
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 12 Jan 2021 10:07:59 +0000 (10:07 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 12 Jan 2021 11:44:55 +0000 (11:44 +0000)
During igt_reset_nop_engine, it was observed that an unexpected failed
engine reset lead to us busywaiting on the stop-ring semaphore (set
during the reset preparations) on the first request afterwards. There was
no explicit MI_ARB_CHECK in this sequence as the presumption was that
the failed MI_SEMAPHORE_WAIT would itself act as an arbitration point.
It did not in this circumstance, so force it.

This patch is based on the assumption that the MI_SEMAPHORE_WAIT failure
to arbitrate is a rare Tigerlake bug, similar to the lite-restore vs
semaphore issues previously seen in the CS. The explicit MI_ARB_CHECK
should always ensure that there is at least one arbitration point in the
request before the MI_SEMAPHORE_WAIT to trigger the IDLE->ACTIVE event.
Upon processing that event, we will clear the stop-ring flag and release
the semaphore from its busywait.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210112100759.32698-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gt/gen8_engine_cs.c

index 1ed9f57..8066b93 100644 (file)
@@ -578,6 +578,7 @@ u32 *gen11_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs)
 
 static u32 *gen12_emit_preempt_busywait(struct i915_request *rq, u32 *cs)
 {
+       *cs++ = MI_ARB_CHECK; /* trigger IDLE->ACTIVE first */
        *cs++ = MI_SEMAPHORE_WAIT_TOKEN |
                MI_SEMAPHORE_GLOBAL_GTT |
                MI_SEMAPHORE_POLL |
@@ -586,7 +587,6 @@ static u32 *gen12_emit_preempt_busywait(struct i915_request *rq, u32 *cs)
        *cs++ = preempt_address(rq->engine);
        *cs++ = 0;
        *cs++ = 0;
-       *cs++ = MI_NOOP;
 
        return cs;
 }