Commit f6a7c21c authored by Chris Wilson's avatar Chris Wilson

drm/i915/execlists: Verify we don't submit two identical CCIDs

Check that we do not submit two contexts into ELSP with the same CCID
[upper portion of the descriptor].

References: https://gitlab.freedesktop.org/drm/intel/-/issues/1793Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200428184751.11257-3-chris@chris-wilson.co.uk
parent 5c4a53e3
...@@ -1612,9 +1612,12 @@ static __maybe_unused bool ...@@ -1612,9 +1612,12 @@ static __maybe_unused bool
assert_pending_valid(const struct intel_engine_execlists *execlists, assert_pending_valid(const struct intel_engine_execlists *execlists,
const char *msg) const char *msg)
{ {
struct intel_engine_cs *engine =
container_of(execlists, typeof(*engine), execlists);
struct i915_request * const *port, *rq; struct i915_request * const *port, *rq;
struct intel_context *ce = NULL; struct intel_context *ce = NULL;
bool sentinel = false; bool sentinel = false;
u32 ccid = -1;
trace_ports(execlists, msg, execlists->pending); trace_ports(execlists, msg, execlists->pending);
...@@ -1623,13 +1626,14 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1623,13 +1626,14 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
return true; return true;
if (!execlists->pending[0]) { if (!execlists->pending[0]) {
GEM_TRACE_ERR("Nothing pending for promotion!\n"); GEM_TRACE_ERR("%s: Nothing pending for promotion!\n",
engine->name);
return false; return false;
} }
if (execlists->pending[execlists_num_ports(execlists)]) { if (execlists->pending[execlists_num_ports(execlists)]) {
GEM_TRACE_ERR("Excess pending[%d] for promotion!\n", GEM_TRACE_ERR("%s: Excess pending[%d] for promotion!\n",
execlists_num_ports(execlists)); engine->name, execlists_num_ports(execlists));
return false; return false;
} }
...@@ -1641,20 +1645,31 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1641,20 +1645,31 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
GEM_BUG_ON(!i915_request_is_active(rq)); GEM_BUG_ON(!i915_request_is_active(rq));
if (ce == rq->context) { if (ce == rq->context) {
GEM_TRACE_ERR("Dup context:%llx in pending[%zd]\n", GEM_TRACE_ERR("%s: Dup context:%llx in pending[%zd]\n",
engine->name,
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; return false;
} }
ce = rq->context; ce = rq->context;
if (ccid == ce->lrc.ccid) {
GEM_TRACE_ERR("%s: Dup ccid:%x context:%llx in pending[%zd]\n",
engine->name,
ccid, ce->timeline->fence_context,
port - execlists->pending);
return false;
}
ccid = ce->lrc.ccid;
/* /*
* Sentinels are supposed to be lonely so they flush the * Sentinels are supposed to be lonely so they flush the
* current exection off the HW. Check that they are the * current exection off the HW. Check that they are the
* only request in the pending submission. * only request in the pending submission.
*/ */
if (sentinel) { if (sentinel) {
GEM_TRACE_ERR("context:%llx after sentinel in pending[%zd]\n", GEM_TRACE_ERR("%s: context:%llx after sentinel in pending[%zd]\n",
engine->name,
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; return false;
...@@ -1662,7 +1677,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1662,7 +1677,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
sentinel = i915_request_has_sentinel(rq); sentinel = i915_request_has_sentinel(rq);
if (sentinel && port != execlists->pending) { if (sentinel && port != execlists->pending) {
GEM_TRACE_ERR("sentinel context:%llx not in prime position[%zd]\n", GEM_TRACE_ERR("%s: sentinel context:%llx not in prime position[%zd]\n",
engine->name,
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
return false; return false;
...@@ -1677,7 +1693,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1677,7 +1693,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
if (i915_active_is_idle(&ce->active) && if (i915_active_is_idle(&ce->active) &&
!intel_context_is_barrier(ce)) { !intel_context_is_barrier(ce)) {
GEM_TRACE_ERR("Inactive context:%llx in pending[%zd]\n", GEM_TRACE_ERR("%s: Inactive context:%llx in pending[%zd]\n",
engine->name,
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
ok = false; ok = false;
...@@ -1685,7 +1702,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1685,7 +1702,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
} }
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("%s: Unpinned context:%llx in pending[%zd]\n",
engine->name,
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
ok = false; ok = false;
...@@ -1693,7 +1711,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists, ...@@ -1693,7 +1711,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
} }
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("%s: Unpinned ring:%llx in pending[%zd]\n",
engine->name,
ce->timeline->fence_context, ce->timeline->fence_context,
port - execlists->pending); port - execlists->pending);
ok = false; ok = false;
......
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