drm/i915: Handle async cancellation in sentinel assert
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>
Wed, 24 Mar 2021 12:13:32 +0000 (12:13 +0000)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 25 Mar 2021 23:58:14 +0000 (00:58 +0100)
With the watchdog cancelling requests asynchronously to preempt-to-busy we
need to relax one assert making it apply only to requests not in error.

v2:
 * Check against the correct request!

v3:
 * Simplify the check to avoid the question of when to sample the fence
   error vs sentinel bit.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20210324121335.2307063-5-tvrtko.ursulin@linux.intel.com
drivers/gpu/drm/i915/gt/intel_execlists_submission.c

index eacc7371a4b97a3a3c100806c2a181410159c918..2578e8cce930606b8a713c1f2d7e20df9e93e455 100644 (file)
@@ -757,9 +757,8 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
 {
        struct intel_engine_cs *engine =
                container_of(execlists, typeof(*engine), execlists);
-       struct i915_request * const *port, *rq;
+       struct i915_request * const *port, *rq, *prev = NULL;
        struct intel_context *ce = NULL;
-       bool sentinel = false;
        u32 ccid = -1;
 
        trace_ports(execlists, msg, execlists->pending);
@@ -809,15 +808,20 @@ assert_pending_valid(const struct intel_engine_execlists *execlists,
                 * Sentinels are supposed to be the last request so they flush
                 * the current execution off the HW. Check that they are the only
                 * request in the pending submission.
+                *
+                * NB: Due to the async nature of preempt-to-busy and request
+                * cancellation we need to handle the case where request
+                * becomes a sentinel in parallel to CSB processing.
                 */
-               if (sentinel) {
+               if (prev && i915_request_has_sentinel(prev) &&
+                   !READ_ONCE(prev->fence.error)) {
                        GEM_TRACE_ERR("%s: context:%llx after sentinel in pending[%zd]\n",
                                      engine->name,
                                      ce->timeline->fence_context,
                                      port - execlists->pending);
                        return false;
                }
-               sentinel = i915_request_has_sentinel(rq);
+               prev = rq;
 
                /*
                 * We want virtual requests to only be in the first slot so