drm/i915/gem: Always test execution status on closing the context
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 28 Sep 2020 22:15:10 +0000 (23:15 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Wed, 30 Sep 2020 18:24:51 +0000 (14:24 -0400)
Verify that if a context is active at the time it is closed, that it is
either persistent and preemptible (with hangcheck running) or it shall
be removed from execution.

Fixes: 9a40bddd47ca ("drm/i915/gt: Expose heartbeat interval via sysfs")
Testcase: igt/gem_ctx_persistence/heartbeat-close
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: <stable@vger.kernel.org> # v5.7+
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200928221510.26044-3-chris@chris-wilson.co.uk
(cherry picked from commit d3bb2f9b5ee66d5e000293edd6b6575e59d11db9)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/i915/gem/i915_gem_context.c

index a548626..4fd3810 100644 (file)
@@ -390,24 +390,6 @@ __context_engines_static(const struct i915_gem_context *ctx)
        return rcu_dereference_protected(ctx->engines, true);
 }
 
-static bool __reset_engine(struct intel_engine_cs *engine)
-{
-       struct intel_gt *gt = engine->gt;
-       bool success = false;
-
-       if (!intel_has_reset_engine(gt))
-               return false;
-
-       if (!test_and_set_bit(I915_RESET_ENGINE + engine->id,
-                             &gt->reset.flags)) {
-               success = intel_engine_reset(engine, NULL) == 0;
-               clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id,
-                                     &gt->reset.flags);
-       }
-
-       return success;
-}
-
 static void __reset_context(struct i915_gem_context *ctx,
                            struct intel_engine_cs *engine)
 {
@@ -431,12 +413,7 @@ static bool __cancel_engine(struct intel_engine_cs *engine)
         * kill the banned context, we fallback to doing a local reset
         * instead.
         */
-       if (IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT) &&
-           !intel_engine_pulse(engine))
-               return true;
-
-       /* If we are unable to send a pulse, try resetting this engine. */
-       return __reset_engine(engine);
+       return intel_engine_pulse(engine) == 0;
 }
 
 static bool
@@ -506,7 +483,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
        return engine;
 }
 
-static void kill_engines(struct i915_gem_engines *engines)
+static void kill_engines(struct i915_gem_engines *engines, bool ban)
 {
        struct i915_gem_engines_iter it;
        struct intel_context *ce;
@@ -521,7 +498,7 @@ static void kill_engines(struct i915_gem_engines *engines)
        for_each_gem_engine(ce, engines, it) {
                struct intel_engine_cs *engine;
 
-               if (intel_context_set_banned(ce))
+               if (ban && intel_context_set_banned(ce))
                        continue;
 
                /*
@@ -534,7 +511,7 @@ static void kill_engines(struct i915_gem_engines *engines)
                engine = active_engine(ce);
 
                /* First attempt to gracefully cancel the context */
-               if (engine && !__cancel_engine(engine))
+               if (engine && !__cancel_engine(engine) && ban)
                        /*
                         * If we are unable to send a preemptive pulse to bump
                         * the context from the GPU, we have to resort to a full
@@ -544,8 +521,10 @@ static void kill_engines(struct i915_gem_engines *engines)
        }
 }
 
-static void kill_stale_engines(struct i915_gem_context *ctx)
+static void kill_context(struct i915_gem_context *ctx)
 {
+       bool ban = (!i915_gem_context_is_persistent(ctx) ||
+                   !ctx->i915->params.enable_hangcheck);
        struct i915_gem_engines *pos, *next;
 
        spin_lock_irq(&ctx->stale.lock);
@@ -558,7 +537,7 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
 
                spin_unlock_irq(&ctx->stale.lock);
 
-               kill_engines(pos);
+               kill_engines(pos, ban);
 
                spin_lock_irq(&ctx->stale.lock);
                GEM_BUG_ON(i915_sw_fence_signaled(&pos->fence));
@@ -570,11 +549,6 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
        spin_unlock_irq(&ctx->stale.lock);
 }
 
-static void kill_context(struct i915_gem_context *ctx)
-{
-       kill_stale_engines(ctx);
-}
-
 static void engines_idle_release(struct i915_gem_context *ctx,
                                 struct i915_gem_engines *engines)
 {
@@ -609,7 +583,7 @@ static void engines_idle_release(struct i915_gem_context *ctx,
 
 kill:
        if (list_empty(&engines->link)) /* raced, already closed */
-               kill_engines(engines);
+               kill_engines(engines, true);
 
        i915_sw_fence_commit(&engines->fence);
 }
@@ -667,9 +641,7 @@ static void context_close(struct i915_gem_context *ctx)
         * case we opt to forcibly kill off all remaining requests on
         * context close.
         */
-       if (!i915_gem_context_is_persistent(ctx) ||
-           !ctx->i915->params.enable_hangcheck)
-               kill_context(ctx);
+       kill_context(ctx);
 
        i915_gem_context_put(ctx);
 }