Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

neighbour: Convert RTM_GETNEIGHTBL to RCU.

neightbl_dump_info() calls these functions for each neigh_tables[]
entry:

1. neightbl_fill_info() for tbl->parms
2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)

Both functions rely on the table lock (read_lock_bh(&tbl->lock))
and RTNL is not needed.

Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.

Note that the first entry of tbl->parms_list is tbl->parms.list and
embedded in neigh_table, so list_next_entry() is safe.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
4ae34be5 35d7c708

+9 -14
+9 -14
net/core/neighbour.c
··· 2176 2176 return -ENOBUFS; 2177 2177 2178 2178 if ((parms->dev && 2179 - nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) || 2179 + nla_put_u32(skb, NDTPA_IFINDEX, READ_ONCE(parms->dev->ifindex))) || 2180 2180 nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) || 2181 2181 nla_put_u32(skb, NDTPA_QUEUE_LENBYTES, 2182 2182 NEIGH_VAR(parms, QUEUE_LEN_BYTES)) || ··· 2228 2228 return -EMSGSIZE; 2229 2229 2230 2230 ndtmsg = nlmsg_data(nlh); 2231 - 2232 - read_lock_bh(&tbl->lock); 2233 2231 ndtmsg->ndtm_family = tbl->family; 2234 2232 ndtmsg->ndtm_pad1 = 0; 2235 2233 ndtmsg->ndtm_pad2 = 0; ··· 2253 2255 .ndtc_proxy_qlen = READ_ONCE(tbl->proxy_queue.qlen), 2254 2256 }; 2255 2257 2256 - rcu_read_lock(); 2257 2258 nht = rcu_dereference(tbl->nht); 2258 2259 ndc.ndtc_hash_rnd = nht->hash_rnd[0]; 2259 2260 ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); 2260 - rcu_read_unlock(); 2261 2261 2262 2262 if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc)) 2263 2263 goto nla_put_failure; ··· 2293 2297 if (neightbl_fill_parms(skb, &tbl->parms) < 0) 2294 2298 goto nla_put_failure; 2295 2299 2296 - read_unlock_bh(&tbl->lock); 2297 2300 nlmsg_end(skb, nlh); 2298 2301 return 0; 2299 2302 2300 2303 nla_put_failure: 2301 - read_unlock_bh(&tbl->lock); 2302 2304 nlmsg_cancel(skb, nlh); 2303 2305 return -EMSGSIZE; 2304 2306 } ··· 2315 2321 return -EMSGSIZE; 2316 2322 2317 2323 ndtmsg = nlmsg_data(nlh); 2318 - 2319 - read_lock_bh(&tbl->lock); 2320 2324 ndtmsg->ndtm_family = tbl->family; 2321 2325 ndtmsg->ndtm_pad1 = 0; 2322 2326 ndtmsg->ndtm_pad2 = 0; ··· 2323 2331 neightbl_fill_parms(skb, parms) < 0) 2324 2332 goto errout; 2325 2333 2326 - read_unlock_bh(&tbl->lock); 2327 2334 nlmsg_end(skb, nlh); 2328 2335 return 0; 2329 2336 errout: 2330 - read_unlock_bh(&tbl->lock); 2331 2337 nlmsg_cancel(skb, nlh); 2332 2338 return -EMSGSIZE; 2333 2339 } ··· 2565 2575 2566 2576 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; 2567 2577 2578 + rcu_read_lock(); 2579 + 2568 2580 for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) { 2569 2581 struct neigh_parms *p; 2570 2582 2571 - tbl = rcu_dereference_rtnl(neigh_tables[tidx]); 2583 + tbl = rcu_dereference(neigh_tables[tidx]); 2572 2584 if (!tbl) 2573 2585 continue; 2574 2586 ··· 2584 2592 2585 2593 nidx = 0; 2586 2594 p = list_next_entry(&tbl->parms, list); 2587 - list_for_each_entry_from(p, &tbl->parms_list, list) { 2595 + list_for_each_entry_from_rcu(p, &tbl->parms_list, list) { 2588 2596 if (!net_eq(neigh_parms_net(p), net)) 2589 2597 continue; 2590 2598 ··· 2604 2612 neigh_skip = 0; 2605 2613 } 2606 2614 out: 2615 + rcu_read_unlock(); 2616 + 2607 2617 cb->args[0] = tidx; 2608 2618 cb->args[1] = nidx; 2609 2619 ··· 3907 3913 {.msgtype = RTM_DELNEIGH, .doit = neigh_delete}, 3908 3914 {.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info, 3909 3915 .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED}, 3910 - {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info}, 3916 + {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info, 3917 + .flags = RTNL_FLAG_DUMP_UNLOCKED}, 3911 3918 {.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set}, 3912 3919 }; 3913 3920