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 seq_file functions to use hlist

Convert seq_file-related neighbour functionality to use neighbour::hash
and the related 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-4-gnaaman@drivenets.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Gilad Naaman and committed by
Jakub Kicinski
00df5e1a d7ddee1a

+48 -56
+48 -56
net/core/neighbour.c
··· 3193 3193 3194 3194 #ifdef CONFIG_PROC_FS 3195 3195 3196 - static struct neighbour *neigh_get_first(struct seq_file *seq) 3196 + static struct neighbour *neigh_get_valid(struct seq_file *seq, 3197 + struct neighbour *n, 3198 + loff_t *pos) 3197 3199 { 3198 3200 struct neigh_seq_state *state = seq->private; 3199 3201 struct net *net = seq_file_net(seq); 3202 + 3203 + if (!net_eq(dev_net(n->dev), net)) 3204 + return NULL; 3205 + 3206 + if (state->neigh_sub_iter) { 3207 + loff_t fakep = 0; 3208 + void *v; 3209 + 3210 + v = state->neigh_sub_iter(state, n, pos ? pos : &fakep); 3211 + if (!v) 3212 + return NULL; 3213 + if (pos) 3214 + return v; 3215 + } 3216 + 3217 + if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) 3218 + return n; 3219 + 3220 + if (READ_ONCE(n->nud_state) & ~NUD_NOARP) 3221 + return n; 3222 + 3223 + return NULL; 3224 + } 3225 + 3226 + static struct neighbour *neigh_get_first(struct seq_file *seq) 3227 + { 3228 + struct neigh_seq_state *state = seq->private; 3200 3229 struct neigh_hash_table *nht = state->nht; 3201 - struct neighbour *n = NULL; 3202 - int bucket; 3230 + struct neighbour *n, *tmp; 3203 3231 3204 3232 state->flags &= ~NEIGH_SEQ_IS_PNEIGH; 3205 - for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) { 3206 - n = rcu_dereference(nht->hash_buckets[bucket]); 3207 3233 3208 - while (n) { 3209 - if (!net_eq(dev_net(n->dev), net)) 3210 - goto next; 3211 - if (state->neigh_sub_iter) { 3212 - loff_t fakep = 0; 3213 - void *v; 3214 - 3215 - v = state->neigh_sub_iter(state, n, &fakep); 3216 - if (!v) 3217 - goto next; 3218 - } 3219 - if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) 3220 - break; 3221 - if (READ_ONCE(n->nud_state) & ~NUD_NOARP) 3222 - break; 3223 - next: 3224 - n = rcu_dereference(n->next); 3234 + while (++state->bucket < (1 << nht->hash_shift)) { 3235 + neigh_for_each_in_bucket(n, &nht->hash_heads[state->bucket]) { 3236 + tmp = neigh_get_valid(seq, n, NULL); 3237 + if (tmp) 3238 + return tmp; 3225 3239 } 3226 - 3227 - if (n) 3228 - break; 3229 3240 } 3230 - state->bucket = bucket; 3231 3241 3232 - return n; 3242 + return NULL; 3233 3243 } 3234 3244 3235 3245 static struct neighbour *neigh_get_next(struct seq_file *seq, ··· 3247 3237 loff_t *pos) 3248 3238 { 3249 3239 struct neigh_seq_state *state = seq->private; 3250 - struct net *net = seq_file_net(seq); 3251 - struct neigh_hash_table *nht = state->nht; 3240 + struct neighbour *tmp; 3252 3241 3253 3242 if (state->neigh_sub_iter) { 3254 3243 void *v = state->neigh_sub_iter(state, n, pos); 3244 + 3255 3245 if (v) 3256 3246 return n; 3257 3247 } 3258 - n = rcu_dereference(n->next); 3259 3248 3260 - while (1) { 3261 - while (n) { 3262 - if (!net_eq(dev_net(n->dev), net)) 3263 - goto next; 3264 - if (state->neigh_sub_iter) { 3265 - void *v = state->neigh_sub_iter(state, n, pos); 3266 - if (v) 3267 - return n; 3268 - goto next; 3269 - } 3270 - if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) 3271 - break; 3272 - 3273 - if (READ_ONCE(n->nud_state) & ~NUD_NOARP) 3274 - break; 3275 - next: 3276 - n = rcu_dereference(n->next); 3249 + hlist_for_each_entry_continue(n, hash) { 3250 + tmp = neigh_get_valid(seq, n, pos); 3251 + if (tmp) { 3252 + n = tmp; 3253 + goto out; 3277 3254 } 3278 - 3279 - if (n) 3280 - break; 3281 - 3282 - if (++state->bucket >= (1 << nht->hash_shift)) 3283 - break; 3284 - 3285 - n = rcu_dereference(nht->hash_buckets[state->bucket]); 3286 3255 } 3287 3256 3257 + n = neigh_get_first(seq); 3258 + out: 3288 3259 if (n && pos) 3289 3260 --(*pos); 3261 + 3290 3262 return n; 3291 3263 } 3292 3264 ··· 3371 3379 struct neigh_seq_state *state = seq->private; 3372 3380 3373 3381 state->tbl = tbl; 3374 - state->bucket = 0; 3382 + state->bucket = -1; 3375 3383 state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH); 3376 3384 3377 3385 rcu_read_lock();