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.

ipv6: use READ_ONCE()/WRITE_ONCE() on fib6_table->fib_seq

Using RTNL to protect ops->fib_rules_seq reads seems a big hammer.

Writes are protected by RTNL.
We can use READ_ONCE() when reading it.

Constify 'struct net' argument of fib6_tables_seq_read() and
fib6_rules_seq_read().

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

authored by

Eric Dumazet and committed by
Jakub Kicinski
e60ea454 16207384

+12 -12
+4 -4
include/net/ip6_fib.h
··· 394 394 struct fib6_node tb6_root; 395 395 struct inet_peer_base tb6_peers; 396 396 unsigned int flags; 397 - unsigned int fib_seq; 397 + unsigned int fib_seq; /* writes protected by rtnl_mutex */ 398 398 struct hlist_head tb6_gc_hlist; /* GC candidates */ 399 399 #define RT6_TABLE_HAS_DFLT_ROUTER BIT(0) 400 400 }; ··· 563 563 int __net_init fib6_notifier_init(struct net *net); 564 564 void __net_exit fib6_notifier_exit(struct net *net); 565 565 566 - unsigned int fib6_tables_seq_read(struct net *net); 566 + unsigned int fib6_tables_seq_read(const struct net *net); 567 567 int fib6_tables_dump(struct net *net, struct notifier_block *nb, 568 568 struct netlink_ext_ack *extack); 569 569 ··· 632 632 bool fib6_rule_default(const struct fib_rule *rule); 633 633 int fib6_rules_dump(struct net *net, struct notifier_block *nb, 634 634 struct netlink_ext_ack *extack); 635 - unsigned int fib6_rules_seq_read(struct net *net); 635 + unsigned int fib6_rules_seq_read(const struct net *net); 636 636 637 637 static inline bool fib6_rules_early_flow_dissect(struct net *net, 638 638 struct sk_buff *skb, ··· 676 676 { 677 677 return 0; 678 678 } 679 - static inline unsigned int fib6_rules_seq_read(struct net *net) 679 + static inline unsigned int fib6_rules_seq_read(const struct net *net) 680 680 { 681 681 return 0; 682 682 }
+1 -1
net/ipv6/fib6_rules.c
··· 56 56 return fib_rules_dump(net, nb, AF_INET6, extack); 57 57 } 58 58 59 - unsigned int fib6_rules_seq_read(struct net *net) 59 + unsigned int fib6_rules_seq_read(const struct net *net) 60 60 { 61 61 return fib_rules_seq_read(net, AF_INET6); 62 62 }
+7 -7
net/ipv6/ip6_fib.c
··· 345 345 346 346 #endif 347 347 348 - unsigned int fib6_tables_seq_read(struct net *net) 348 + unsigned int fib6_tables_seq_read(const struct net *net) 349 349 { 350 350 unsigned int h, fib_seq = 0; 351 351 352 352 rcu_read_lock(); 353 353 for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { 354 - struct hlist_head *head = &net->ipv6.fib_table_hash[h]; 355 - struct fib6_table *tb; 354 + const struct hlist_head *head = &net->ipv6.fib_table_hash[h]; 355 + const struct fib6_table *tb; 356 356 357 357 hlist_for_each_entry_rcu(tb, head, tb6_hlist) 358 - fib_seq += tb->fib_seq; 358 + fib_seq += READ_ONCE(tb->fib_seq); 359 359 } 360 360 rcu_read_unlock(); 361 361 ··· 400 400 .rt = rt, 401 401 }; 402 402 403 - rt->fib6_table->fib_seq++; 403 + WRITE_ONCE(rt->fib6_table->fib_seq, rt->fib6_table->fib_seq + 1); 404 404 return call_fib6_notifiers(net, event_type, &info.info); 405 405 } 406 406 ··· 416 416 .nsiblings = nsiblings, 417 417 }; 418 418 419 - rt->fib6_table->fib_seq++; 419 + WRITE_ONCE(rt->fib6_table->fib_seq, rt->fib6_table->fib_seq + 1); 420 420 return call_fib6_notifiers(net, event_type, &info.info); 421 421 } 422 422 ··· 427 427 .nsiblings = rt->fib6_nsiblings, 428 428 }; 429 429 430 - rt->fib6_table->fib_seq++; 430 + WRITE_ONCE(rt->fib6_table->fib_seq, rt->fib6_table->fib_seq + 1); 431 431 return call_fib6_notifiers(net, FIB_EVENT_ENTRY_REPLACE, &info.info); 432 432 } 433 433