]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
neighbour: Drop read_lock_bh(&tbl->lock) in pneigh_dump_table().
authorKuniyuki Iwashima <kuniyu@google.com>
Wed, 16 Jul 2025 22:08:15 +0000 (22:08 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 17 Jul 2025 23:25:21 +0000 (16:25 -0700)
Now pneigh_entry is guaranteed to be alive during the
RCU critical section even without holding tbl->lock.

Let's drop read_lock_bh(&tbl->lock) and use rcu_dereference()
to iterate tbl->phash_buckets[] in pneigh_dump_table()

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-11-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/neighbour.c

index 50ab95ecbcd6a07b2441058a70cc9a6b4cbe68d7..3ef797212618eed9a67a40b7ef9d7126606e1455 100644 (file)
@@ -2808,14 +2808,12 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
        if (filter->dev_idx || filter->master_idx)
                flags |= NLM_F_DUMP_FILTERED;
 
-       read_lock_bh(&tbl->lock);
-
        for (h = s_h; h <= PNEIGH_HASHMASK; h++) {
                if (h > s_h)
                        s_idx = 0;
-               for (n = rcu_dereference_protected(tbl->phash_buckets[h], 1), idx = 0;
+               for (n = rcu_dereference(tbl->phash_buckets[h]), idx = 0;
                     n;
-                    n = rcu_dereference_protected(n->next, 1)) {
+                    n = rcu_dereference(n->next)) {
                        if (idx < s_idx || pneigh_net(n) != net)
                                goto next;
                        if (neigh_ifindex_filtered(n->dev, filter->dev_idx) ||
@@ -2824,16 +2822,13 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                        err = pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
                                               cb->nlh->nlmsg_seq,
                                               RTM_NEWNEIGH, flags, tbl);
-                       if (err < 0) {
-                               read_unlock_bh(&tbl->lock);
+                       if (err < 0)
                                goto out;
-                       }
                next:
                        idx++;
                }
        }
 
-       read_unlock_bh(&tbl->lock);
 out:
        cb->args[3] = h;
        cb->args[4] = idx;