Commit 651dabe2 authored by Chris Wilson's avatar Chris Wilson Committed by Rodrigo Vivi

drm/i915/gem: Always test execution status on closing the context

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: 9a40bddd ("drm/i915/gt: Expose heartbeat interval via sysfs")
Testcase: igt/gem_ctx_persistence/heartbeat-close
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: <stable@vger.kernel.org> # v5.7+
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: default avatarJoonas 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: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent ca65fc0d
...@@ -390,24 +390,6 @@ __context_engines_static(const struct i915_gem_context *ctx) ...@@ -390,24 +390,6 @@ __context_engines_static(const struct i915_gem_context *ctx)
return rcu_dereference_protected(ctx->engines, true); 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, static void __reset_context(struct i915_gem_context *ctx,
struct intel_engine_cs *engine) struct intel_engine_cs *engine)
{ {
...@@ -431,12 +413,7 @@ static bool __cancel_engine(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 * kill the banned context, we fallback to doing a local reset
* instead. * instead.
*/ */
if (IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT) && return intel_engine_pulse(engine) == 0;
!intel_engine_pulse(engine))
return true;
/* If we are unable to send a pulse, try resetting this engine. */
return __reset_engine(engine);
} }
static bool static bool
...@@ -506,7 +483,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce) ...@@ -506,7 +483,7 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
return engine; 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 i915_gem_engines_iter it;
struct intel_context *ce; struct intel_context *ce;
...@@ -521,7 +498,7 @@ static void kill_engines(struct i915_gem_engines *engines) ...@@ -521,7 +498,7 @@ static void kill_engines(struct i915_gem_engines *engines)
for_each_gem_engine(ce, engines, it) { for_each_gem_engine(ce, engines, it) {
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
if (intel_context_set_banned(ce)) if (ban && intel_context_set_banned(ce))
continue; continue;
/* /*
...@@ -534,7 +511,7 @@ static void kill_engines(struct i915_gem_engines *engines) ...@@ -534,7 +511,7 @@ static void kill_engines(struct i915_gem_engines *engines)
engine = active_engine(ce); engine = active_engine(ce);
/* First attempt to gracefully cancel the context */ /* 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 * If we are unable to send a preemptive pulse to bump
* the context from the GPU, we have to resort to a full * 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) ...@@ -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; struct i915_gem_engines *pos, *next;
spin_lock_irq(&ctx->stale.lock); spin_lock_irq(&ctx->stale.lock);
...@@ -558,7 +537,7 @@ static void kill_stale_engines(struct i915_gem_context *ctx) ...@@ -558,7 +537,7 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
spin_unlock_irq(&ctx->stale.lock); spin_unlock_irq(&ctx->stale.lock);
kill_engines(pos); kill_engines(pos, ban);
spin_lock_irq(&ctx->stale.lock); spin_lock_irq(&ctx->stale.lock);
GEM_BUG_ON(i915_sw_fence_signaled(&pos->fence)); GEM_BUG_ON(i915_sw_fence_signaled(&pos->fence));
...@@ -570,11 +549,6 @@ static void kill_stale_engines(struct i915_gem_context *ctx) ...@@ -570,11 +549,6 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
spin_unlock_irq(&ctx->stale.lock); 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, static void engines_idle_release(struct i915_gem_context *ctx,
struct i915_gem_engines *engines) struct i915_gem_engines *engines)
{ {
...@@ -609,7 +583,7 @@ static void engines_idle_release(struct i915_gem_context *ctx, ...@@ -609,7 +583,7 @@ static void engines_idle_release(struct i915_gem_context *ctx,
kill: kill:
if (list_empty(&engines->link)) /* raced, already closed */ if (list_empty(&engines->link)) /* raced, already closed */
kill_engines(engines); kill_engines(engines, true);
i915_sw_fence_commit(&engines->fence); i915_sw_fence_commit(&engines->fence);
} }
...@@ -667,9 +641,7 @@ static void context_close(struct i915_gem_context *ctx) ...@@ -667,9 +641,7 @@ static void context_close(struct i915_gem_context *ctx)
* case we opt to forcibly kill off all remaining requests on * case we opt to forcibly kill off all remaining requests on
* context close. * context close.
*/ */
if (!i915_gem_context_is_persistent(ctx) || kill_context(ctx);
!ctx->i915->params.enable_hangcheck)
kill_context(ctx);
i915_gem_context_put(ctx); i915_gem_context_put(ctx);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment