Skip to content
Snippets Groups Projects
Commit 2471eb5f authored by Chris Wilson's avatar Chris Wilson Committed by Jani Nikula
Browse files

drm/i915: Prevent timeline updates whilst performing reset


As the fence may be signaled concurrently from an interrupt on another
device, it is possible for the list of requests on the timeline to be
modified as we walk it. Take both (the context's timeline and the global
timeline) locks to prevent such modifications.

Fixes: 80b204bc ("drm/i915: Enable multiple timelines")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: <drm-intel-fixes@lists.freedesktop.org>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161223145804.6605-10-chris@chris-wilson.co.uk


(cherry picked from commit 00c25e3f)
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 64d1461c
Branches
Tags
No related merge requests found
...@@ -2730,6 +2730,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) ...@@ -2730,6 +2730,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
struct i915_gem_context *incomplete_ctx; struct i915_gem_context *incomplete_ctx;
struct intel_timeline *timeline; struct intel_timeline *timeline;
unsigned long flags;
bool ring_hung; bool ring_hung;
if (engine->irq_seqno_barrier) if (engine->irq_seqno_barrier)
...@@ -2765,13 +2766,20 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) ...@@ -2765,13 +2766,20 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
if (i915_gem_context_is_default(incomplete_ctx)) if (i915_gem_context_is_default(incomplete_ctx))
return; return;
timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
spin_lock_irqsave(&engine->timeline->lock, flags);
spin_lock(&timeline->lock);
list_for_each_entry_continue(request, &engine->timeline->requests, link) list_for_each_entry_continue(request, &engine->timeline->requests, link)
if (request->ctx == incomplete_ctx) if (request->ctx == incomplete_ctx)
reset_request(request); reset_request(request);
timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
list_for_each_entry(request, &timeline->requests, link) list_for_each_entry(request, &timeline->requests, link)
reset_request(request); reset_request(request);
spin_unlock(&timeline->lock);
spin_unlock_irqrestore(&engine->timeline->lock, flags);
} }
void i915_gem_reset(struct drm_i915_private *dev_priv) void i915_gem_reset(struct drm_i915_private *dev_priv)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment