drm/i915/selftests: Synchronize checking active status with retirement
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 22 Oct 2019 11:21:11 +0000 (12:21 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 22 Oct 2019 20:12:23 +0000 (21:12 +0100)
If retirement is running on another thread, we may inspect the status of
the i915_active before its retirement callback is complete. As we expect
it to be running synchronously, we can wait for any callback to complete
by acquiring the i915_active.mutex.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Andi Shyti <andi.shyti@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191022112111.9317-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c

index 1f5ab59..5af27c3 100644 (file)
@@ -49,12 +49,20 @@ static struct pulse *pulse_create(void)
        return p;
 }
 
+static void pulse_unlock_wait(struct pulse *p)
+{
+       mutex_lock(&p->active.mutex);
+       mutex_unlock(&p->active.mutex);
+}
+
 static int __live_idle_pulse(struct intel_engine_cs *engine,
                             int (*fn)(struct intel_engine_cs *cs))
 {
        struct pulse *p;
        int err;
 
+       GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
+
        p = pulse_create();
        if (!p)
                return -ENOMEM;
@@ -73,16 +81,21 @@ static int __live_idle_pulse(struct intel_engine_cs *engine,
        i915_active_release(&p->active);
 
        GEM_BUG_ON(i915_active_is_idle(&p->active));
+       GEM_BUG_ON(llist_empty(&engine->barrier_tasks));
 
        err = fn(engine);
        if (err)
                goto out;
 
+       GEM_BUG_ON(!llist_empty(&engine->barrier_tasks));
+
        if (intel_gt_retire_requests_timeout(engine->gt, HZ / 5)) {
                err = -ETIME;
                goto out;
        }
 
+       pulse_unlock_wait(p); /* synchronize with the retirement callback */
+
        if (!i915_active_is_idle(&p->active)) {
                pr_err("%s: heartbeat pulse did not flush idle tasks\n",
                       engine->name);