Merge drm/drm-next into drm-intel-gt-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / gt / intel_execlists_submission.c
index 4b909cb88cdfb7b7422bd5cc1629f536f9422032..0187bc72310d6f8fa4cb7fa7492dc8b4638ee5d9 100644 (file)
@@ -1241,6 +1241,9 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine,
        if (!rq)
                return 0;
 
+       /* Only allow ourselves to force reset the currently active context */
+       engine->execlists.preempt_target = rq;
+
        /* Force a fast reset for terminated contexts (ignoring sysfs!) */
        if (unlikely(intel_context_is_banned(rq->context) || bad_request(rq)))
                return INTEL_CONTEXT_BANNED_PREEMPT_TIMEOUT_MS;
@@ -2427,8 +2430,24 @@ static void execlists_submission_tasklet(struct tasklet_struct *t)
        GEM_BUG_ON(inactive - post > ARRAY_SIZE(post));
 
        if (unlikely(preempt_timeout(engine))) {
+               const struct i915_request *rq = *engine->execlists.active;
+
+               /*
+                * If after the preempt-timeout expired, we are still on the
+                * same active request/context as before we initiated the
+                * preemption, reset the engine.
+                *
+                * However, if we have processed a CS event to switch contexts,
+                * but not yet processed the CS event for the pending
+                * preemption, reset the timer allowing the new context to
+                * gracefully exit.
+                */
                cancel_timer(&engine->execlists.preempt);
-               engine->execlists.error_interrupt |= ERROR_PREEMPT;
+               if (rq == engine->execlists.preempt_target)
+                       engine->execlists.error_interrupt |= ERROR_PREEMPT;
+               else
+                       set_timer_ms(&engine->execlists.preempt,
+                                    active_preempt_timeout(engine, rq));
        }
 
        if (unlikely(READ_ONCE(engine->execlists.error_interrupt))) {
@@ -3452,9 +3471,9 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
 
        if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) {
                if (intel_engine_has_preemption(engine))
-                       engine->emit_bb_start = gen125_emit_bb_start;
+                       engine->emit_bb_start = xehp_emit_bb_start;
                else
-                       engine->emit_bb_start = gen125_emit_bb_start_noarb;
+                       engine->emit_bb_start = xehp_emit_bb_start_noarb;
        } else {
                if (intel_engine_has_preemption(engine))
                        engine->emit_bb_start = gen8_emit_bb_start;