aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <[email protected]>2017-11-15 12:14:58 +0000
committerJani Nikula <[email protected]>2017-11-21 11:39:56 +0200
commit6e068270b7883836e4717e262d96d1c43690862a (patch)
treeb2c688b2d592c59c87a184bd0029326e2cb87e80
parentdcd1d8302a06b0a0e5d6f9b6851fa4a5579e79b0 (diff)
drm/i915: Clear breadcrumb node when cancelling signaling
When we call intel_engine_cancel_signaling() to stop reporting when a request is completed via an asynchronous signal, we remove that request from the breadcrumb wait queue. However, we may be concurrently processing that request in the signaler itself, the actual operations on the request's node itself are serialised but we do not actually clear the waiter after removing it from the tree allowing both parties to attempt to do so and corrupting the rbtree. (Previously removing from the breadcrumb wait queue could only be done on behalf of i915_wait_request, so this race could not happen). Reported-by: "He, Bo" <[email protected]> Fixes: 9eb143bbec7d ("drm/i915: Allow a request to be cancelled") Signed-off-by: Chris Wilson <[email protected]> Cc: "He, Bo" <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Cc: MichaƂ Winiarski <[email protected]> Cc: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Joonas Lahtinen <[email protected]> (cherry picked from commit c534612e780c4a2c8ef5bfc11583c7d58436baca) Signed-off-by: Jani Nikula <[email protected]>
-rw-r--r--drivers/gpu/drm/i915/intel_breadcrumbs.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 48e1ba01ccf8..5f8b9f1f40f1 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -517,6 +517,7 @@ static void __intel_engine_remove_wait(struct intel_engine_cs *engine,
GEM_BUG_ON(RB_EMPTY_NODE(&wait->node));
rb_erase(&wait->node, &b->waiters);
+ RB_CLEAR_NODE(&wait->node);
out:
GEM_BUG_ON(b->irq_wait == wait);