Commit eed7ec52 authored by Chris Wilson's avatar Chris Wilson

drm/i915/execlists: Clear user-active flag on preemption completion

When cancelling the requests and clearing out the ports following a
successful preemption completion, also clear the active flag. I had
assumed that all preemptions would be followed by an immediate dequeue
(preserving the active user flag), but under rare circumstances we may
be triggering a preemption for the second port only for it to have
completed before the preemotion kicks in; leaving execlists->active set
even though the system is now idle.

We can clear the flag inside the common execlists_cancel_port_requests()
as the other users also expect the semantics of active being cleared.

Fixes: f6322edd ("drm/i915/preemption: Allow preemption between submission ports")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180324125829.27026-1-chris@chris-wilson.co.uk
parent 7487508e
...@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) ...@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
* know the next preemption status we see corresponds * know the next preemption status we see corresponds
* to this ELSP update. * to this ELSP update.
*/ */
GEM_BUG_ON(!execlists_is_active(execlists,
EXECLISTS_ACTIVE_USER));
GEM_BUG_ON(!port_count(&port[0])); GEM_BUG_ON(!port_count(&port[0]));
if (port_count(&port[0]) > 1) if (port_count(&port[0]) > 1)
goto unlock; goto unlock;
...@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) ...@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
memset(port, 0, sizeof(*port)); memset(port, 0, sizeof(*port));
port++; port++;
} }
execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
} }
static void clear_gtiir(struct intel_engine_cs *engine) static void clear_gtiir(struct intel_engine_cs *engine)
...@@ -1042,6 +1046,11 @@ static void execlists_submission_tasklet(unsigned long data) ...@@ -1042,6 +1046,11 @@ static void execlists_submission_tasklet(unsigned long data)
if (fw) if (fw)
intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); intel_uncore_forcewake_put(dev_priv, execlists->fw_domains);
/* If the engine is now idle, so should be the flag; and vice versa. */
GEM_BUG_ON(execlists_is_active(&engine->execlists,
EXECLISTS_ACTIVE_USER) ==
!port_isset(engine->execlists.port));
} }
static void queue_request(struct intel_engine_cs *engine, static void queue_request(struct intel_engine_cs *engine,
......
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