Commit 99fe4a5f authored by Chris Wilson's avatar Chris Wilson

drm/i915: Wake up the bottom-half if we steal their interrupt

Following on from the scenario Tvrtko envisioned to explain a hard-to-hit
race with multiple first waiters, we could also then race in the
__i915_request_irq_complete() and the bottom-half may miss the vital
irq-seqno barrier and so go to sleep not noticing their seqno is
complete.

v2: unlock, not double lock the rcu_read_lock.

Fixes: 3d5564e9 ("drm/i915: Only apply one barrier after...")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1467805142-22219-2-git-send-email-chris@chris-wilson.co.uk
parent 04171313
......@@ -3998,7 +3998,10 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req)
* is woken.
*/
if (engine->irq_seqno_barrier &&
READ_ONCE(engine->breadcrumbs.tasklet) == current &&
cmpxchg_relaxed(&engine->irq_posted, 1, 0)) {
struct task_struct *tsk;
/* The ordering of irq_posted versus applying the barrier
* is crucial. The clearing of the current irq_posted must
* be visible before we perform the barrier operation,
......@@ -4012,6 +4015,25 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req)
* seqno update.
*/
engine->irq_seqno_barrier(engine);
/* If we consume the irq, but we are no longer the bottom-half,
* the real bottom-half may not have serialised their own
* seqno check with the irq-barrier (i.e. may have inspected
* the seqno before we believe it coherent since they see
* irq_posted == false but we are still running).
*/
rcu_read_lock();
tsk = READ_ONCE(engine->breadcrumbs.tasklet);
if (tsk && tsk != current)
/* Note that if the bottom-half is changed as we
* are sending the wake-up, the new bottom-half will
* be woken by whomever made the change. We only have
* to worry about when we steal the irq-posted for
* ourself.
*/
wake_up_process(tsk);
rcu_read_unlock();
if (i915_gem_request_completed(req))
return true;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment