rcu: Use WRITE_ONCE() for assignments to ->next for rculist_nulls
authorAlan Huang <mmpgouride@gmail.com>
Thu, 6 Jul 2023 10:28:48 +0000 (10:28 +0000)
committerPaul E. McKenney <paulmck@kernel.org>
Wed, 16 Aug 2023 21:27:41 +0000 (14:27 -0700)
When the objects managed by rculist_nulls are allocated with
SLAB_TYPESAFE_BY_RCU, old readers may still hold references to an object
even though it is just now being added, which means the modification of
->next is visible to readers.  This patch therefore uses WRITE_ONCE()
for assignments to ->next.

Signed-off-by: Alan Huang <mmpgouride@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
include/linux/rculist_nulls.h

index ba4c00dd8005a9fb0bdfa761972f14caa57fc4db..89186c499dd4721dd374864f7d193c2cd0fd8c73 100644 (file)
@@ -101,7 +101,7 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
 {
        struct hlist_nulls_node *first = h->first;
 
-       n->next = first;
+       WRITE_ONCE(n->next, first);
        WRITE_ONCE(n->pprev, &h->first);
        rcu_assign_pointer(hlist_nulls_first_rcu(h), n);
        if (!is_a_nulls(first))
@@ -137,7 +137,7 @@ static inline void hlist_nulls_add_tail_rcu(struct hlist_nulls_node *n,
                last = i;
 
        if (last) {
-               n->next = last->next;
+               WRITE_ONCE(n->next, last->next);
                n->pprev = &last->next;
                rcu_assign_pointer(hlist_nulls_next_rcu(last), n);
        } else {