summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-01-05 17:00:59 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-01-05 21:06:20 +0000
commit7ec73b7e36d0bf165cea77770a490fcdf4418e93 (patch)
tree751dbaf60a7ebb6f41c0d0bff0afb6c63bfd3fca
parentb7163936bd99dab90a71c2496295f62f2b4874ab (diff)
downloadop-kernel-dev-7ec73b7e36d0bf165cea77770a490fcdf4418e93.zip
op-kernel-dev-7ec73b7e36d0bf165cea77770a490fcdf4418e93.tar.gz
drm/i915: Only skip requests once a context is banned
If we skip before banning, we have an inconsistent interface between execbuf still queueing valid request but those requests already queued being cancelled. If we only cancel the pending requests once we stop accepting new requests, the user interface is more consistent. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Cc: <stable@vger.kernel.org> # v4.9+ Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170105170059.344-1-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 70ddff3..e604672 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2734,7 +2734,7 @@ void i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
static void i915_gem_reset_engine(struct intel_engine_cs *engine)
{
struct drm_i915_gem_request *request;
- struct i915_gem_context *incomplete_ctx;
+ struct i915_gem_context *hung_ctx;
struct intel_timeline *timeline;
unsigned long flags;
bool ring_hung;
@@ -2746,6 +2746,8 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
if (!request)
return;
+ hung_ctx = request->ctx;
+
ring_hung = engine->hangcheck.stalled;
if (engine->hangcheck.seqno != intel_engine_get_seqno(engine)) {
DRM_DEBUG_DRIVER("%s pardoned, was guilty? %s\n",
@@ -2755,9 +2757,9 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
}
if (ring_hung)
- i915_gem_context_mark_guilty(request->ctx);
+ i915_gem_context_mark_guilty(hung_ctx);
else
- i915_gem_context_mark_innocent(request->ctx);
+ i915_gem_context_mark_innocent(hung_ctx);
if (!ring_hung)
return;
@@ -2768,6 +2770,10 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
/* Setup the CS to resume from the breadcrumb of the hung request */
engine->reset_hw(engine, request);
+ /* If this context is now banned, skip all of its pending requests. */
+ if (!i915_gem_context_is_banned(hung_ctx))
+ return;
+
/* Users of the default context do not rely on logical state
* preserved between batches. They have to emit full state on
* every batch and so it is safe to execute queued requests following
@@ -2776,17 +2782,16 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
* Other contexts preserve state, now corrupt. We want to skip all
* queued requests that reference the corrupt context.
*/
- incomplete_ctx = request->ctx;
- if (i915_gem_context_is_default(incomplete_ctx))
+ if (i915_gem_context_is_default(hung_ctx))
return;
- timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
+ 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 == incomplete_ctx)
+ if (request->ctx == hung_ctx)
reset_request(request);
list_for_each_entry(request, &timeline->requests, link)
OpenPOWER on IntegriCloud