The final i915_request_put() can release the last reference to a
signaled request, freeing it synchronously (kmem_cache_free) before the
RCU iterator advances to read rq->signal_link.next. Grab the next
request up front, so the loop does not touch a request that may already
have been freed.

Fixes: c744d50363b7 ("drm/i915/gt: Split the breadcrumb spinlock between global 
and contexts")
Cc: [email protected]
Signed-off-by: Wentao Liang <[email protected]>
---
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index f840e98792cd..90bc32b526b8 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -213,7 +213,7 @@ static void signal_irq_work(struct irq_work *work)
        for (ce = list_first_or_null_rcu(&b->signalers, typeof(*ce), 
signal_link);
             ce;
             ce = cn) {
-               struct i915_request *rq;
+               struct i915_request *rq, *rn;
 
                /*
                 * Grab the next signaler up front, as dropping the final
@@ -223,9 +223,16 @@ static void signal_irq_work(struct irq_work *work)
                cn = list_next_or_null_rcu(&b->signalers, &ce->signal_link,
                                           typeof(*cn), signal_link);
 
-               list_for_each_entry_rcu(rq, &ce->signals, signal_link) {
+               for (rq = list_first_or_null_rcu(&ce->signals,
+                                                typeof(*rq), signal_link);
+                    rq;
+                    rq = rn) {
                        bool release;
 
+                       rn = list_next_or_null_rcu(&ce->signals,
+                                                  &rq->signal_link,
+                                                  typeof(*rn), signal_link);
+
                        if (!__i915_request_is_complete(rq))
                                break;
 
-- 
2.34.1

Reply via email to