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 iteration to use hlist+macro

Remove all usage of the bare neighbour::next pointer,
replacing them with neighbour::hash and its for_each macro.

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-5-gnaaman@drivenets.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Gilad Naaman and committed by
Jakub Kicinski
0e3bcb0f 00df5e1a

+20 -34
+1 -4
include/net/neighbour.h
··· 311 311 u32 hash_val; 312 312 313 313 hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); 314 - for (n = rcu_dereference(nht->hash_buckets[hash_val]); 315 - n != NULL; 316 - n = rcu_dereference(n->next)) { 314 + neigh_for_each_in_bucket_rcu(n, &nht->hash_heads[hash_val]) 317 315 if (n->dev == dev && key_eq(n, pkey)) 318 316 return n; 319 - } 320 317 321 318 return NULL; 322 319 }
+19 -30
net/core/neighbour.c
··· 387 387 lockdep_is_held(&tbl->lock)); 388 388 389 389 for (i = 0; i < (1 << nht->hash_shift); i++) { 390 - struct neighbour *n; 391 390 struct neighbour __rcu **np = &nht->hash_buckets[i]; 391 + struct hlist_node *tmp; 392 + struct neighbour *n; 392 393 393 - while ((n = rcu_dereference_protected(*np, 394 - lockdep_is_held(&tbl->lock))) != NULL) { 394 + neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[i]) { 395 395 if (dev && n->dev != dev) { 396 396 np = &n->next; 397 397 continue; ··· 587 587 return old_nht; 588 588 589 589 for (i = 0; i < (1 << old_nht->hash_shift); i++) { 590 - struct neighbour *n, *next; 590 + struct hlist_node *tmp; 591 + struct neighbour *n; 591 592 592 - for (n = rcu_dereference_protected(old_nht->hash_buckets[i], 593 - lockdep_is_held(&tbl->lock)); 594 - n != NULL; 595 - n = next) { 593 + neigh_for_each_in_bucket_safe(n, tmp, &old_nht->hash_heads[i]) { 596 594 hash = tbl->hash(n->primary_key, n->dev, 597 595 new_nht->hash_rnd); 598 596 599 597 hash >>= (32 - new_nht->hash_shift); 600 - next = rcu_dereference_protected(n->next, 601 - lockdep_is_held(&tbl->lock)); 602 598 603 599 rcu_assign_pointer(n->next, 604 600 rcu_dereference_protected( ··· 689 693 goto out_tbl_unlock; 690 694 } 691 695 692 - for (n1 = rcu_dereference_protected(nht->hash_buckets[hash_val], 693 - lockdep_is_held(&tbl->lock)); 694 - n1 != NULL; 695 - n1 = rcu_dereference_protected(n1->next, 696 - lockdep_is_held(&tbl->lock))) { 696 + neigh_for_each_in_bucket(n1, &nht->hash_heads[hash_val]) { 697 697 if (dev == n1->dev && !memcmp(n1->primary_key, n->primary_key, key_len)) { 698 698 if (want_ref) 699 699 neigh_hold(n1); ··· 941 949 static void neigh_periodic_work(struct work_struct *work) 942 950 { 943 951 struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work); 944 - struct neighbour *n; 945 - struct neighbour __rcu **np; 946 - unsigned int i; 947 952 struct neigh_hash_table *nht; 953 + struct neighbour __rcu **np; 954 + struct hlist_node *tmp; 955 + struct neighbour *n; 956 + unsigned int i; 948 957 949 958 NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs); 950 959 ··· 972 979 for (i = 0 ; i < (1 << nht->hash_shift); i++) { 973 980 np = &nht->hash_buckets[i]; 974 981 975 - while ((n = rcu_dereference_protected(*np, 976 - lockdep_is_held(&tbl->lock))) != NULL) { 982 + neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[i]) { 977 983 unsigned int state; 978 984 979 985 write_lock(&n->lock); ··· 2722 2730 for (h = s_h; h < (1 << nht->hash_shift); h++) { 2723 2731 if (h > s_h) 2724 2732 s_idx = 0; 2725 - for (n = rcu_dereference(nht->hash_buckets[h]), idx = 0; 2726 - n != NULL; 2727 - n = rcu_dereference(n->next)) { 2733 + idx = 0; 2734 + neigh_for_each_in_bucket_rcu(n, &nht->hash_heads[h]) { 2728 2735 if (idx < s_idx || !net_eq(dev_net(n->dev), net)) 2729 2736 goto next; 2730 2737 if (neigh_ifindex_filtered(n->dev, filter->dev_idx) || ··· 3090 3099 for (chain = 0; chain < (1 << nht->hash_shift); chain++) { 3091 3100 struct neighbour *n; 3092 3101 3093 - for (n = rcu_dereference(nht->hash_buckets[chain]); 3094 - n != NULL; 3095 - n = rcu_dereference(n->next)) 3102 + neigh_for_each_in_bucket(n, &nht->hash_heads[chain]) 3096 3103 cb(n, cookie); 3097 3104 } 3098 3105 read_unlock_bh(&tbl->lock); ··· 3102 3113 void __neigh_for_each_release(struct neigh_table *tbl, 3103 3114 int (*cb)(struct neighbour *)) 3104 3115 { 3105 - int chain; 3106 3116 struct neigh_hash_table *nht; 3117 + int chain; 3107 3118 3108 3119 nht = rcu_dereference_protected(tbl->nht, 3109 3120 lockdep_is_held(&tbl->lock)); 3110 3121 for (chain = 0; chain < (1 << nht->hash_shift); chain++) { 3111 - struct neighbour *n; 3112 3122 struct neighbour __rcu **np; 3123 + struct hlist_node *tmp; 3124 + struct neighbour *n; 3113 3125 3114 3126 np = &nht->hash_buckets[chain]; 3115 - while ((n = rcu_dereference_protected(*np, 3116 - lockdep_is_held(&tbl->lock))) != NULL) { 3127 + neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[chain]) { 3117 3128 int release; 3118 3129 3119 3130 write_lock(&n->lock);