summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem_request.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-11-23 18:26:30 +0300
committerChris Wilson <chris@chris-wilson.co.uk>2017-11-23 19:12:04 +0300
commitb1c24a6137af11fca49192a42face03cacbd7fc5 (patch)
tree557beb020f4447a4b66262864d5596cc46b50ef2 /drivers/gpu/drm/i915/i915_gem_request.c
parentc83a8d4a2ec93c53f78e109dee5e21953485cbfd (diff)
downloadlinux-b1c24a6137af11fca49192a42face03cacbd7fc5.tar.xz
drm/i915: Unwind incomplete legacy context switches
The legacy context switch for ringbuffer submission is multistaged, where each of those stages may fail. However, we were updating global state after some stages, and so we had to force the incomplete request to be submitted because we could not unwind. Save the global state before performing the switches, and so enable us to unwind back to the previous global state should any phase fail. We then must cancel the request instead of submitting it should the construction fail. v2: s/saved_ctx/from_ctx/; s/ctx/to_ctx/ etc. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171123152631.31385-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_request.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 7325469ce754..a90bdd26571f 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -719,25 +719,19 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
/* Unconditionally invalidate GPU caches and TLBs. */
ret = engine->emit_flush(req, EMIT_INVALIDATE);
if (ret)
- goto err_ctx;
+ goto err_unwind;
ret = engine->request_alloc(req);
- if (ret) {
- /*
- * Past the point-of-no-return. Since we may have updated
- * global state after partially completing the request alloc,
- * we need to commit any commands so far emitted in the
- * request to the HW.
- */
- __i915_add_request(req, false);
- return ERR_PTR(ret);
- }
+ if (ret)
+ goto err_unwind;
/* Check that we didn't interrupt ourselves with a new request */
GEM_BUG_ON(req->timeline->seqno != req->fence.seqno);
return req;
-err_ctx:
+err_unwind:
+ req->ring->emit = req->head;
+
/* Make sure we didn't add ourselves to external state before freeing */
GEM_BUG_ON(!list_empty(&req->active_list));
GEM_BUG_ON(!list_empty(&req->priotree.signalers_list));