drm/i915: Treat i915_reset_engine() as guilty until proven innocent
If we are resetting just one engine, we know it has stalled. So we can pass the stalled parameter directly to i915_gem_reset_engine(), which alleviates the necessity to poke at the generic engine->hangcheck.stalled magic variable, leaving that under control of hangcheck as its name implies. Other than simplifying by removing the indirect parameter along this path, this allows us to introduce new reset mechanisms that run independently of hangcheck. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Michel Thierry <michel.thierry@intel.com> Cc: Jeff McGee <jeff.mcgee@intel.com> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Reviewed-by: Michel Thierry <michel.thierry@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180406220354.18911-1-chris@chris-wilson.co.uk
This commit is contained in:
@@ -2990,20 +2990,6 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
|
||||
return active;
|
||||
}
|
||||
|
||||
static bool engine_stalled(struct intel_engine_cs *engine)
|
||||
{
|
||||
if (!engine->hangcheck.stalled)
|
||||
return false;
|
||||
|
||||
/* Check for possible seqno movement after hang declaration */
|
||||
if (engine->hangcheck.seqno != intel_engine_get_seqno(engine)) {
|
||||
DRM_DEBUG_DRIVER("%s pardoned\n", engine->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure irq handler finishes, and not run again.
|
||||
* Also return the active request so that we only search for it once.
|
||||
@@ -3142,7 +3128,8 @@ static void engine_skip_context(struct i915_request *request)
|
||||
/* Returns the request if it was guilty of the hang */
|
||||
static struct i915_request *
|
||||
i915_gem_reset_request(struct intel_engine_cs *engine,
|
||||
struct i915_request *request)
|
||||
struct i915_request *request,
|
||||
bool stalled)
|
||||
{
|
||||
/* The guilty request will get skipped on a hung engine.
|
||||
*
|
||||
@@ -3165,7 +3152,15 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
|
||||
* subsequent hangs.
|
||||
*/
|
||||
|
||||
if (engine_stalled(engine)) {
|
||||
if (i915_request_completed(request)) {
|
||||
GEM_TRACE("%s pardoned global=%d (fence %llx:%d), current %d\n",
|
||||
engine->name, request->global_seqno,
|
||||
request->fence.context, request->fence.seqno,
|
||||
intel_engine_get_seqno(engine));
|
||||
stalled = false;
|
||||
}
|
||||
|
||||
if (stalled) {
|
||||
i915_gem_context_mark_guilty(request->ctx);
|
||||
skip_request(request);
|
||||
|
||||
@@ -3196,7 +3191,8 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
|
||||
}
|
||||
|
||||
void i915_gem_reset_engine(struct intel_engine_cs *engine,
|
||||
struct i915_request *request)
|
||||
struct i915_request *request,
|
||||
bool stalled)
|
||||
{
|
||||
/*
|
||||
* Make sure this write is visible before we re-enable the interrupt
|
||||
@@ -3206,7 +3202,7 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine,
|
||||
smp_store_mb(engine->irq_posted, 0);
|
||||
|
||||
if (request)
|
||||
request = i915_gem_reset_request(engine, request);
|
||||
request = i915_gem_reset_request(engine, request, stalled);
|
||||
|
||||
if (request) {
|
||||
DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
|
||||
@@ -3229,7 +3225,9 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
|
||||
for_each_engine(engine, dev_priv, id) {
|
||||
struct i915_gem_context *ctx;
|
||||
|
||||
i915_gem_reset_engine(engine, engine->hangcheck.active_request);
|
||||
i915_gem_reset_engine(engine,
|
||||
engine->hangcheck.active_request,
|
||||
engine->hangcheck.stalled);
|
||||
ctx = fetch_and_zero(&engine->last_retired_context);
|
||||
if (ctx)
|
||||
engine->context_unpin(engine, ctx);
|
||||
|
Reference in New Issue
Block a user