summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_breadcrumbs.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-11-15 12:14:58 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-11-16 14:17:08 +0000
commitc534612e780c4a2c8ef5bfc11583c7d58436baca (patch)
treec4a0af347740943d2cfad7042c893d8bc9ae26c1 /drivers/gpu/drm/i915/intel_breadcrumbs.c
parentd5653ec322ff132c2d6976ca0b909e0a9d1da6af (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" <bo.he@intel.com> Fixes: 9eb143bbec7d ("drm/i915: Allow a request to be cancelled") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: "He, Bo" <bo.he@intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: MichaƂ Winiarski <michal.winiarski@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171115121458.24655-1-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_breadcrumbs.c')
-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 4c4fbf5f20f9..5ae2d276f7f3 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -549,6 +549,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);