Skip to content

Commit

Permalink
drm/i915: Prevent timeline updates whilst performing reset
Browse files Browse the repository at this point in the history
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: 80b204b ("drm/i915: Enable multiple timelines")
Signed-off-by: Chris 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: Mika 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 00c25e3)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
  • Loading branch information
Chris Wilson authored and Jani Nikula committed Jan 3, 2017
1 parent 64d1461 commit 2471eb5
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2730,6 +2730,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
struct drm_i915_gem_request *request;
struct i915_gem_context *incomplete_ctx;
struct intel_timeline *timeline;
unsigned long flags;
bool ring_hung;

if (engine->irq_seqno_barrier)
Expand Down Expand Up @@ -2765,13 +2766,20 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
if (i915_gem_context_is_default(incomplete_ctx))
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)
if (request->ctx == incomplete_ctx)
reset_request(request);

timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
list_for_each_entry(request, &timeline->requests, link)
reset_request(request);

spin_unlock(&timeline->lock);
spin_unlock_irqrestore(&engine->timeline->lock, flags);
}

void i915_gem_reset(struct drm_i915_private *dev_priv)
Expand Down

0 comments on commit 2471eb5

Please sign in to comment.