Commit c95d31c3 authored by Chris Wilson's avatar Chris Wilson

drm/i915/execlists: Lock the request while validating it during promotion

Since the request is already on the HW as we perform its validation, it
and even its subsequent barrier may be concurrently retired before we
process the assertions. If it is retired already and so off the HW, our
assertions become void and we need to ignore them.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112363Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191121103546.146487-1-chris@chris-wilson.co.uk
parent 090a82e9
...@@ -1291,38 +1291,53 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1291,38 +1291,53 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
} }
for (port = execlists->pending; (rq = *port); port++) { for (port = execlists->pending; (rq = *port); port++) {
unsigned long flags;
bool ok = true;
if (ce == rq->hw_context) { if (ce == rq->hw_context) {
GEM_TRACE_ERR("Dup context:%llx in pending[%zd]\n", GEM_TRACE_ERR("Dup context:%llx in pending[%zd]\n",
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; return false;
} }
ce = rq->hw_context; ce = rq->hw_context;
/* Hold tightly onto the lock to prevent concurrent retires! */
spin_lock_irqsave_nested(&rq->lock, flags,
SINGLE_DEPTH_NESTING);
if (i915_request_completed(rq)) if (i915_request_completed(rq))
continue; goto unlock;
if (i915_active_is_idle(&ce->active) && if (i915_active_is_idle(&ce->active) &&
!i915_gem_context_is_kernel(ce->gem_context)) { !i915_gem_context_is_kernel(ce->gem_context)) {
GEM_TRACE_ERR("Inactive context:%llx in pending[%zd]\n", GEM_TRACE_ERR("Inactive context:%llx in pending[%zd]\n",
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; ok = false;
goto unlock;
} }
if (!i915_vma_is_pinned(ce->state)) { if (!i915_vma_is_pinned(ce->state)) {
GEM_TRACE_ERR("Unpinned context:%llx in pending[%zd]\n", GEM_TRACE_ERR("Unpinned context:%llx in pending[%zd]\n",
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; ok = false;
goto unlock;
} }
if (!i915_vma_is_pinned(ce->ring->vma)) { if (!i915_vma_is_pinned(ce->ring->vma)) {
GEM_TRACE_ERR("Unpinned ring:%llx in pending[%zd]\n", GEM_TRACE_ERR("Unpinned ring:%llx in pending[%zd]\n",
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; ok = false;
goto unlock;
} }
unlock:
spin_unlock_irqrestore(&rq->lock, flags);
if (!ok)
return false;
} }
return ce; return ce;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment