diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-11-23 18:26:30 +0300 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-11-23 19:12:04 +0300 |
commit | b1c24a6137af11fca49192a42face03cacbd7fc5 (patch) | |
tree | 557beb020f4447a4b66262864d5596cc46b50ef2 /drivers/gpu/drm/i915/i915_gem_request.c | |
parent | c83a8d4a2ec93c53f78e109dee5e21953485cbfd (diff) | |
download | linux-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.c | 18 |
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)); |