On 15/03/2017 14:01, Chris Wilson wrote:
Before walking the rbtree of waiters (marking them as complete and waking
them), decouple the interrupt handler. This prevents a race between the
missed waiter waking up and removing its intel_wait (which skips
checking the lock) and the interrupt handler dereferencing the
intel_wait. (Though we do not expect to encounter waiters during idle!)

Fixes: e1c0c91bdaec ("drm/i915: Wake up all waiters before idling")
Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuopp...@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursu...@intel.com>
---
 drivers/gpu/drm/i915/intel_breadcrumbs.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 31e7c25013a4..ebcb595001fc 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -179,7 +179,7 @@ void __intel_engine_disarm_breadcrumbs(struct 
intel_engine_cs *engine)
 void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
 {
        struct intel_breadcrumbs *b = &engine->breadcrumbs;
-       struct intel_wait *wait, *n;
+       struct intel_wait *wait, *n, *first;

        if (!b->irq_armed)
                return;
@@ -190,18 +190,19 @@ void intel_engine_disarm_breadcrumbs(struct 
intel_engine_cs *engine)
         */

        spin_lock_irq(&b->rb_lock);
+
+       spin_lock(&b->irq_lock);
+       first = fetch_and_zero(&b->irq_wait);
+       __intel_engine_disarm_breadcrumbs(engine);
+       spin_unlock(&b->irq_lock);
+
        rbtree_postorder_for_each_entry_safe(wait, n, &b->waiters, node) {
                RB_CLEAR_NODE(&wait->node);
-               if (wake_up_process(wait->tsk) && wait == b->irq_wait)
+               if (wake_up_process(wait->tsk) && wait == first)
                        missed_breadcrumb(engine);
        }
        b->waiters = RB_ROOT;

-       spin_lock(&b->irq_lock);
-       b->irq_wait = NULL;
-       __intel_engine_disarm_breadcrumbs(engine);
-       spin_unlock(&b->irq_lock);
-
        spin_unlock_irq(&b->rb_lock);
 }



Reviewed-by: Tvrtko Ursulin <tvrtko.ursu...@intel.com>

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to