aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-12-23 09:58:04 -0500
committerJani Nikula <jani.nikula@intel.com>2017-01-03 04:41:57 -0500
commit2471eb5fb6e1433e28426ece235e3730348019ec (patch)
tree72c3347b2022652f8e539284ba6f265c454e6cd8
parent64d1461ce0c3b8ecc1c6b61f4ad1c1d10ce971a3 (diff)
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: 80b204bce8f2 ("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 00c25e3f40083a6d5f1111955baccd287ee49258) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5d146f9f4aad..1e505d30b71e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2730,6 +2730,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
2730 struct drm_i915_gem_request *request; 2730 struct drm_i915_gem_request *request;
2731 struct i915_gem_context *incomplete_ctx; 2731 struct i915_gem_context *incomplete_ctx;
2732 struct intel_timeline *timeline; 2732 struct intel_timeline *timeline;
2733 unsigned long flags;
2733 bool ring_hung; 2734 bool ring_hung;
2734 2735
2735 if (engine->irq_seqno_barrier) 2736 if (engine->irq_seqno_barrier)
@@ -2765,13 +2766,20 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
2765 if (i915_gem_context_is_default(incomplete_ctx)) 2766 if (i915_gem_context_is_default(incomplete_ctx))
2766 return; 2767 return;
2767 2768
2769 timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
2770
2771 spin_lock_irqsave(&engine->timeline->lock, flags);
2772 spin_lock(&timeline->lock);
2773
2768 list_for_each_entry_continue(request, &engine->timeline->requests, link) 2774 list_for_each_entry_continue(request, &engine->timeline->requests, link)
2769 if (request->ctx == incomplete_ctx) 2775 if (request->ctx == incomplete_ctx)
2770 reset_request(request); 2776 reset_request(request);
2771 2777
2772 timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
2773 list_for_each_entry(request, &timeline->requests, link) 2778 list_for_each_entry(request, &timeline->requests, link)
2774 reset_request(request); 2779 reset_request(request);
2780
2781 spin_unlock(&timeline->lock);
2782 spin_unlock_irqrestore(&engine->timeline->lock, flags);
2775} 2783}
2776 2784
2777void i915_gem_reset(struct drm_i915_private *dev_priv) 2785void i915_gem_reset(struct drm_i915_private *dev_priv)