drm/i915: Do not short-circuit tasklets during reset
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 13 Jul 2018 20:35:28 +0000 (21:35 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 13 Jul 2018 21:32:20 +0000 (22:32 +0100)
Inside intel_engine_is_idle(), we flush the tasklet to ensure that is
being run in a timely fashion (ksoftirqd has taught us to expect the
worst). However, if we are in the middle of reset, the HW may not yet be
ready to execute the submission tasklet and so we must respect the
disable flag.

Fixes: dd0cf235d81f ("drm/i915: Speed up idle detection by kicking the tasklets")
Testcase: igt/drv_selftest/live_hangcheck
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180713203529.1973-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/intel_engine_cs.c

index 220050107c486661823aaea179c8ce091b97a0ba..2d1952849d69ffec45b64360cc7d1baf78e0b0ba 100644 (file)
@@ -989,16 +989,18 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
 
        /* Waiting to drain ELSP? */
        if (READ_ONCE(engine->execlists.active)) {
-               struct intel_engine_execlists *execlists = &engine->execlists;
+               struct tasklet_struct *t = &engine->execlists.tasklet;
 
                local_bh_disable();
-               if (tasklet_trylock(&execlists->tasklet)) {
-                       execlists->tasklet.func(execlists->tasklet.data);
-                       tasklet_unlock(&execlists->tasklet);
+               if (tasklet_trylock(t)) {
+                       /* Must wait for any GPU reset in progress. */
+                       if (__tasklet_is_enabled(t))
+                               t->func(t->data);
+                       tasklet_unlock(t);
                }
                local_bh_enable();
 
-               if (READ_ONCE(execlists->active))
+               if (READ_ONCE(engine->execlists.active))
                        return false;
        }