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: Remove bare neighbour::next pointer

Remove the now-unused neighbour::next pointer, leaving struct neighbour
solely with the hlist_node implementation.

Signed-off-by: Gilad Naaman <gnaaman@drivenets.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20241107160444.2913124-6-gnaaman@drivenets.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Gilad Naaman and committed by
Jakub Kicinski
a01a67ab 0e3bcb0f

+12 -84
+1 -3
include/net/neighbour.h
··· 135 135 #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) 136 136 137 137 struct neighbour { 138 - struct neighbour __rcu *next; 139 138 struct hlist_node hash; 140 139 struct neigh_table *tbl; 141 140 struct neigh_parms *parms; ··· 190 191 #define NEIGH_NUM_HASH_RND 4 191 192 192 193 struct neigh_hash_table { 193 - struct neighbour __rcu **hash_buckets; 194 194 struct hlist_head *hash_heads; 195 195 unsigned int hash_shift; 196 196 __u32 hash_rnd[NEIGH_NUM_HASH_RND]; ··· 352 354 int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags, 353 355 u32 nlmsg_pid); 354 356 void __neigh_set_probe_once(struct neighbour *neigh); 355 - bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl); 357 + bool neigh_remove_one(struct neighbour *ndel); 356 358 void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); 357 359 int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev); 358 360 int neigh_carrier_down(struct neigh_table *tbl, struct net_device *dev);
+10 -80
net/core/neighbour.c
··· 204 204 } 205 205 } 206 206 207 - static bool neigh_del(struct neighbour *n, struct neighbour __rcu **np, 208 - struct neigh_table *tbl) 207 + bool neigh_remove_one(struct neighbour *n) 209 208 { 210 209 bool retval = false; 211 210 212 211 write_lock(&n->lock); 213 212 if (refcount_read(&n->refcnt) == 1) { 214 - struct neighbour *neigh; 215 - 216 - neigh = rcu_dereference_protected(n->next, 217 - lockdep_is_held(&tbl->lock)); 218 - rcu_assign_pointer(*np, neigh); 219 213 hlist_del_rcu(&n->hash); 220 214 neigh_mark_dead(n); 221 215 retval = true; ··· 218 224 if (retval) 219 225 neigh_cleanup_and_release(n); 220 226 return retval; 221 - } 222 - 223 - bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl) 224 - { 225 - struct neigh_hash_table *nht; 226 - void *pkey = ndel->primary_key; 227 - u32 hash_val; 228 - struct neighbour *n; 229 - struct neighbour __rcu **np; 230 - 231 - nht = rcu_dereference_protected(tbl->nht, 232 - lockdep_is_held(&tbl->lock)); 233 - hash_val = tbl->hash(pkey, ndel->dev, nht->hash_rnd); 234 - hash_val = hash_val >> (32 - nht->hash_shift); 235 - 236 - np = &nht->hash_buckets[hash_val]; 237 - while ((n = rcu_dereference_protected(*np, 238 - lockdep_is_held(&tbl->lock)))) { 239 - if (n == ndel) 240 - return neigh_del(n, np, tbl); 241 - np = &n->next; 242 - } 243 - return false; 244 227 } 245 228 246 229 static int neigh_forced_gc(struct neigh_table *tbl) ··· 247 276 remove = true; 248 277 write_unlock(&n->lock); 249 278 250 - if (remove && neigh_remove_one(n, tbl)) 279 + if (remove && neigh_remove_one(n)) 251 280 shrunk++; 252 281 if (shrunk >= max_clean) 253 282 break; ··· 358 387 lockdep_is_held(&tbl->lock)); 359 388 360 389 for (i = 0; i < (1 << nht->hash_shift); i++) { 361 - struct neighbour __rcu **np = &nht->hash_buckets[i]; 362 390 struct hlist_node *tmp; 363 391 struct neighbour *n; 364 392 365 393 neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[i]) { 366 - if (dev && n->dev != dev) { 367 - np = &n->next; 394 + if (dev && n->dev != dev) 368 395 continue; 369 - } 370 - if (skip_perm && n->nud_state & NUD_PERMANENT) { 371 - np = &n->next; 396 + if (skip_perm && n->nud_state & NUD_PERMANENT) 372 397 continue; 373 - } 374 - rcu_assign_pointer(*np, 375 - rcu_dereference_protected(n->next, 376 - lockdep_is_held(&tbl->lock))); 398 + 377 399 hlist_del_rcu(&n->hash); 378 400 write_lock(&n->lock); 379 401 neigh_del_timer(n); ··· 495 531 496 532 static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) 497 533 { 498 - size_t hash_heads_size = (1 << shift) * sizeof(struct hlist_head); 499 - size_t size = (1 << shift) * sizeof(struct neighbour *); 500 - struct neighbour __rcu **buckets; 534 + size_t size = (1 << shift) * sizeof(struct hlist_head); 501 535 struct hlist_head *hash_heads; 502 536 struct neigh_hash_table *ret; 503 537 int i; ··· 504 542 if (!ret) 505 543 return NULL; 506 544 507 - buckets = kvzalloc(size, GFP_ATOMIC); 508 - if (!buckets) { 509 - kfree(ret); 510 - return NULL; 511 - } 512 - hash_heads = kvzalloc(hash_heads_size, GFP_ATOMIC); 545 + hash_heads = kvzalloc(size, GFP_ATOMIC); 513 546 if (!hash_heads) { 514 - kvfree(buckets); 515 547 kfree(ret); 516 548 return NULL; 517 549 } 518 - ret->hash_buckets = buckets; 519 550 ret->hash_heads = hash_heads; 520 551 ret->hash_shift = shift; 521 552 for (i = 0; i < NEIGH_NUM_HASH_RND; i++) ··· 522 567 struct neigh_hash_table, 523 568 rcu); 524 569 525 - kvfree(nht->hash_buckets); 526 570 kvfree(nht->hash_heads); 527 571 kfree(nht); 528 572 } ··· 550 596 551 597 hash >>= (32 - new_nht->hash_shift); 552 598 553 - rcu_assign_pointer(n->next, 554 - rcu_dereference_protected( 555 - new_nht->hash_buckets[hash], 556 - lockdep_is_held(&tbl->lock))); 557 - rcu_assign_pointer(new_nht->hash_buckets[hash], n); 558 599 hlist_del_rcu(&n->hash); 559 600 hlist_add_head_rcu(&n->hash, &new_nht->hash_heads[hash]); 560 601 } ··· 654 705 list_add_tail(&n->managed_list, &n->tbl->managed_list); 655 706 if (want_ref) 656 707 neigh_hold(n); 657 - rcu_assign_pointer(n->next, 658 - rcu_dereference_protected(nht->hash_buckets[hash_val], 659 - lockdep_is_held(&tbl->lock))); 660 - rcu_assign_pointer(nht->hash_buckets[hash_val], n); 661 708 hlist_add_head_rcu(&n->hash, &nht->hash_heads[hash_val]); 662 709 write_unlock_bh(&tbl->lock); 663 710 neigh_dbg(2, "neigh %p is created\n", n); ··· 887 942 { 888 943 struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work); 889 944 struct neigh_hash_table *nht; 890 - struct neighbour __rcu **np; 891 945 struct hlist_node *tmp; 892 946 struct neighbour *n; 893 947 unsigned int i; ··· 914 970 goto out; 915 971 916 972 for (i = 0 ; i < (1 << nht->hash_shift); i++) { 917 - np = &nht->hash_buckets[i]; 918 - 919 973 neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[i]) { 920 974 unsigned int state; 921 975 ··· 923 981 if ((state & (NUD_PERMANENT | NUD_IN_TIMER)) || 924 982 (n->flags & NTF_EXT_LEARNED)) { 925 983 write_unlock(&n->lock); 926 - goto next_elt; 984 + continue; 927 985 } 928 986 929 987 if (time_before(n->used, n->confirmed) && ··· 934 992 (state == NUD_FAILED || 935 993 !time_in_range_open(jiffies, n->used, 936 994 n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { 937 - rcu_assign_pointer(*np, 938 - rcu_dereference_protected(n->next, 939 - lockdep_is_held(&tbl->lock))); 940 995 hlist_del_rcu(&n->hash); 941 996 neigh_mark_dead(n); 942 997 write_unlock(&n->lock); ··· 941 1002 continue; 942 1003 } 943 1004 write_unlock(&n->lock); 944 - 945 - next_elt: 946 - np = &n->next; 947 1005 } 948 1006 /* 949 1007 * It's fine to release lock here, even if hash table ··· 1887 1951 NETLINK_CB(skb).portid, extack); 1888 1952 write_lock_bh(&tbl->lock); 1889 1953 neigh_release(neigh); 1890 - neigh_remove_one(neigh, tbl); 1954 + neigh_remove_one(neigh); 1891 1955 write_unlock_bh(&tbl->lock); 1892 1956 1893 1957 out: ··· 3044 3108 nht = rcu_dereference_protected(tbl->nht, 3045 3109 lockdep_is_held(&tbl->lock)); 3046 3110 for (chain = 0; chain < (1 << nht->hash_shift); chain++) { 3047 - struct neighbour __rcu **np; 3048 3111 struct hlist_node *tmp; 3049 3112 struct neighbour *n; 3050 3113 3051 - np = &nht->hash_buckets[chain]; 3052 3114 neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[chain]) { 3053 3115 int release; 3054 3116 3055 3117 write_lock(&n->lock); 3056 3118 release = cb(n); 3057 3119 if (release) { 3058 - rcu_assign_pointer(*np, 3059 - rcu_dereference_protected(n->next, 3060 - lockdep_is_held(&tbl->lock))); 3061 3120 hlist_del_rcu(&n->hash); 3062 3121 neigh_mark_dead(n); 3063 - } else 3064 - np = &n->next; 3122 + } 3065 3123 write_unlock(&n->lock); 3066 3124 if (release) 3067 3125 neigh_cleanup_and_release(n);
+1 -1
net/ipv4/arp.c
··· 1215 1215 NEIGH_UPDATE_F_ADMIN, 0); 1216 1216 write_lock_bh(&tbl->lock); 1217 1217 neigh_release(neigh); 1218 - neigh_remove_one(neigh, tbl); 1218 + neigh_remove_one(neigh); 1219 1219 write_unlock_bh(&tbl->lock); 1220 1220 } 1221 1221