summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/gt/intel_lrc.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index b65bc06855b0..da72794f3707 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1291,38 +1291,53 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
}
for (port = execlists->pending; (rq = *port); port++) {
+ unsigned long flags;
+ bool ok = true;
+
if (ce == rq->hw_context) {
GEM_TRACE_ERR("Dup context:%llx in pending[%zd]\n",
ce->timeline->fence_context,
port - execlists->pending);
return false;
}
-
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))
- continue;
+ goto unlock;
if (i915_active_is_idle(&ce->active) &&
!i915_gem_context_is_kernel(ce->gem_context)) {
GEM_TRACE_ERR("Inactive context:%llx in pending[%zd]\n",
ce->timeline->fence_context,
port - execlists->pending);
- return false;
+ ok = false;
+ goto unlock;
}
if (!i915_vma_is_pinned(ce->state)) {
GEM_TRACE_ERR("Unpinned context:%llx in pending[%zd]\n",
ce->timeline->fence_context,
port - execlists->pending);
- return false;
+ ok = false;
+ goto unlock;
}
if (!i915_vma_is_pinned(ce->ring->vma)) {
GEM_TRACE_ERR("Unpinned ring:%llx in pending[%zd]\n",
ce->timeline->fence_context,
port - execlists->pending);
- return false;
+ ok = false;
+ goto unlock;
}
+
+unlock:
+ spin_unlock_irqrestore(&rq->lock, flags);
+ if (!ok)
+ return false;
}
return ce;