active_preempt_timeout(engine, rq));
}
+static bool completed(const struct i915_request *rq)
+{
+ if (i915_request_has_sentinel(rq))
+ return false;
+
+ return __i915_request_is_complete(rq);
+}
+
static void execlists_dequeue(struct intel_engine_cs *engine)
{
struct intel_engine_execlists * const execlists = &engine->execlists;
struct i915_request **port = execlists->pending;
struct i915_request ** const last_port = port + execlists->port_mask;
- struct i915_request *last = *execlists->active;
+ struct i915_request *last, * const *active;
struct virtual_engine *ve;
struct rb_node *rb;
bool submit = false;
* i.e. we will retrigger preemption following the ack in case
* of trouble.
*
- * In theory we can skip over completed contexts that have not
- * yet been processed by events (as those events are in flight):
- *
- * while ((last = *active) && i915_request_completed(last))
- * active++;
- *
- * However, the GPU cannot handle this as it will ultimately
- * find itself trying to jump back into a context it has just
- * completed and barf.
*/
+ active = execlists->active;
+ while ((last = *active) && completed(last))
+ active++;
if (last) {
- if (__i915_request_is_complete(last)) {
- goto check_secondary;
- } else if (need_preempt(engine, last)) {
+ if (need_preempt(engine, last)) {
ENGINE_TRACE(engine,
"preempting last=%llx:%lld, prio=%d, hint=%d\n",
last->fence.context,
* we hopefully coalesce several updates into a single
* submission.
*/
-check_secondary:
- if (!list_is_last(&last->sched.link,
- &engine->active.requests)) {
+ if (active[1]) {
/*
* Even if ELSP[1] is occupied and not worthy
* of timeslices, our queue might be.
* of ordered contexts.
*/
if (submit &&
- memcmp(execlists->active,
+ memcmp(active,
execlists->pending,
(port - execlists->pending) * sizeof(*port))) {
*port = NULL;
execlists_schedule_in(*port, port - execlists->pending);
WRITE_ONCE(execlists->yield, -1);
- set_preempt_timeout(engine, *execlists->active);
+ set_preempt_timeout(engine, *active);
execlists_submit_ports(engine);
} else {
ring_set_paused(engine, 0);