|
@@ -217,7 +217,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
|
|
struct intel_wait *wait, *n;
|
|
struct intel_wait *wait, *n;
|
|
|
|
|
|
if (!b->irq_armed)
|
|
if (!b->irq_armed)
|
|
- return;
|
|
|
|
|
|
+ goto wakeup_signaler;
|
|
|
|
|
|
/*
|
|
/*
|
|
* We only disarm the irq when we are idle (all requests completed),
|
|
* We only disarm the irq when we are idle (all requests completed),
|
|
@@ -242,6 +242,14 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
|
|
b->waiters = RB_ROOT;
|
|
b->waiters = RB_ROOT;
|
|
|
|
|
|
spin_unlock_irq(&b->rb_lock);
|
|
spin_unlock_irq(&b->rb_lock);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The signaling thread may be asleep holding a reference to a request,
|
|
|
|
+ * that had its signaling cancelled prior to being preempted. We need
|
|
|
|
+ * to kick the signaler, just in case, to release any such reference.
|
|
|
|
+ */
|
|
|
|
+wakeup_signaler:
|
|
|
|
+ wake_up_process(b->signaler);
|
|
}
|
|
}
|
|
|
|
|
|
static bool use_fake_irq(const struct intel_breadcrumbs *b)
|
|
static bool use_fake_irq(const struct intel_breadcrumbs *b)
|
|
@@ -686,23 +694,15 @@ static int intel_breadcrumbs_signaler(void *arg)
|
|
}
|
|
}
|
|
|
|
|
|
if (unlikely(do_schedule)) {
|
|
if (unlikely(do_schedule)) {
|
|
- DEFINE_WAIT(exec);
|
|
|
|
-
|
|
|
|
if (kthread_should_park())
|
|
if (kthread_should_park())
|
|
kthread_parkme();
|
|
kthread_parkme();
|
|
|
|
|
|
- if (kthread_should_stop()) {
|
|
|
|
- GEM_BUG_ON(request);
|
|
|
|
|
|
+ if (unlikely(kthread_should_stop())) {
|
|
|
|
+ i915_gem_request_put(request);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- if (request)
|
|
|
|
- add_wait_queue(&request->execute, &exec);
|
|
|
|
-
|
|
|
|
schedule();
|
|
schedule();
|
|
-
|
|
|
|
- if (request)
|
|
|
|
- remove_wait_queue(&request->execute, &exec);
|
|
|
|
}
|
|
}
|
|
i915_gem_request_put(request);
|
|
i915_gem_request_put(request);
|
|
} while (1);
|
|
} while (1);
|