Add a new function for skipping all pending requests for a context in order to make engine reset flow more readable. Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Signed-off-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem.c | 59 ++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 021d1e9..a83a4cc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2604,13 +2604,26 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) if (__i915_gem_request_completed(request)) continue; + GEM_BUG_ON(request->engine != engine); return request; } return NULL; } -static void reset_request(struct drm_i915_gem_request *request) +void i915_gem_reset_prepare(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + /* Ensure irq handler finishes, and not run again. */ + for_each_engine(engine, dev_priv, id) + tasklet_kill(&engine->irq_tasklet); + + i915_gem_revoke_fences(dev_priv); +} + +static void skip_request(struct drm_i915_gem_request *request) { void *vaddr = request->ring->vaddr; u32 head; @@ -2629,24 +2642,33 @@ static void reset_request(struct drm_i915_gem_request *request) dma_fence_set_error(&request->fence, -EIO); } -void i915_gem_reset_prepare(struct drm_i915_private *dev_priv) +static void engine_skip_context(struct drm_i915_gem_request *request) { - struct intel_engine_cs *engine; - enum intel_engine_id id; + struct intel_engine_cs *engine = request->engine; + struct i915_gem_context *hung_ctx = request->ctx; + struct intel_timeline *timeline; + unsigned long flags; - /* Ensure irq handler finishes, and not run again. */ - for_each_engine(engine, dev_priv, id) - tasklet_kill(&engine->irq_tasklet); + timeline = i915_gem_context_lookup_timeline(hung_ctx, engine); - i915_gem_revoke_fences(dev_priv); + spin_lock_irqsave(&engine->timeline->lock, flags); + spin_lock(&timeline->lock); + + list_for_each_entry_continue(request, &engine->timeline->requests, link) + if (request->ctx == hung_ctx) + skip_request(request); + + list_for_each_entry(request, &timeline->requests, link) + skip_request(request); + + spin_unlock(&timeline->lock); + spin_unlock_irqrestore(&engine->timeline->lock, flags); } static void i915_gem_reset_engine(struct intel_engine_cs *engine) { struct drm_i915_gem_request *request; struct i915_gem_context *hung_ctx; - struct intel_timeline *timeline; - unsigned long flags; bool ring_hung; if (engine->irq_seqno_barrier) @@ -2668,7 +2690,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) if (ring_hung) { i915_gem_context_mark_guilty(hung_ctx); - reset_request(request); + skip_request(request); } else { i915_gem_context_mark_innocent(hung_ctx); dma_fence_set_error(&request->fence, -EAGAIN); @@ -2696,20 +2718,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) if (i915_gem_context_is_default(hung_ctx)) return; - timeline = i915_gem_context_lookup_timeline(hung_ctx, engine); - - spin_lock_irqsave(&engine->timeline->lock, flags); - spin_lock(&timeline->lock); - - list_for_each_entry_continue(request, &engine->timeline->requests, link) - if (request->ctx == hung_ctx) - reset_request(request); - - list_for_each_entry(request, &timeline->requests, link) - reset_request(request); - - spin_unlock(&timeline->lock); - spin_unlock_irqrestore(&engine->timeline->lock, flags); + engine_skip_context(request); } void i915_gem_reset_finish(struct drm_i915_private *dev_priv) -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx