drm/i915/execlists: Always clear ring_pause if we do not submit
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 24 Jun 2019 09:20:09 +0000 (10:20 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 24 Jun 2019 10:42:37 +0000 (11:42 +0100)
In the unlikely case (thank you CI!), we may find ourselves wanting to
issue a preemption but having no runnable requests left. In this case,
we set the semaphore before computing the preemption and so must unset
it before forgetting (or else we leave the machine busywaiting until the
next request comes along and so likely hang).

v2: Replace readback with only a wmb after asserting the semaphore

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190624092009.30189-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gt/intel_lrc.c

index c8a0c9b327646433be99e5bf8e63d36f6a60f5f3..28685ba91a2c74ca4632ef1eb4c5d0058d09d84c 100644 (file)
@@ -240,7 +240,8 @@ ring_set_paused(const struct intel_engine_cs *engine, int state)
         * until the dword is false.
         */
        engine->status_page.addr[I915_GEM_HWS_PREEMPT] = state;
-       wmb();
+       if (state)
+               wmb();
 }
 
 static inline struct i915_priolist *to_priolist(struct rb_node *rb)
@@ -1243,6 +1244,8 @@ done:
                *port = execlists_schedule_in(last, port - execlists->pending);
                memset(port + 1, 0, (last_port - port) * sizeof(*port));
                execlists_submit_ports(engine);
+       } else {
+               ring_set_paused(engine, 0);
        }
 }