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

ipv4: convert fib_num_tclassid_users to atomic_t

Before commit faa041a40b9f ("ipv4: Create cleanup helper for fib_nh")
changes to net->ipv4.fib_num_tclassid_users were protected by RTNL.

After the change, this is no longer the case, as free_fib_info_rcu()
runs after rcu grace period, without rtnl being held.

Fixes: faa041a40b9f ("ipv4: Create cleanup helper for fib_nh")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: David Ahern <dsahern@kernel.org>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
213f5f8f a37a0ee4

+7 -7
+1 -1
include/net/ip_fib.h
··· 438 438 #ifdef CONFIG_IP_ROUTE_CLASSID 439 439 static inline int fib_num_tclassid_users(struct net *net) 440 440 { 441 - return net->ipv4.fib_num_tclassid_users; 441 + return atomic_read(&net->ipv4.fib_num_tclassid_users); 442 442 } 443 443 #else 444 444 static inline int fib_num_tclassid_users(struct net *net)
+1 -1
include/net/netns/ipv4.h
··· 65 65 bool fib_has_custom_local_routes; 66 66 bool fib_offload_disabled; 67 67 #ifdef CONFIG_IP_ROUTE_CLASSID 68 - int fib_num_tclassid_users; 68 + atomic_t fib_num_tclassid_users; 69 69 #endif 70 70 struct hlist_head *fib_table_hash; 71 71 struct sock *fibnl;
+1 -1
net/ipv4/fib_frontend.c
··· 1582 1582 int error; 1583 1583 1584 1584 #ifdef CONFIG_IP_ROUTE_CLASSID 1585 - net->ipv4.fib_num_tclassid_users = 0; 1585 + atomic_set(&net->ipv4.fib_num_tclassid_users, 0); 1586 1586 #endif 1587 1587 error = ip_fib_net_init(net); 1588 1588 if (error < 0)
+2 -2
net/ipv4/fib_rules.c
··· 264 264 if (tb[FRA_FLOW]) { 265 265 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); 266 266 if (rule4->tclassid) 267 - net->ipv4.fib_num_tclassid_users++; 267 + atomic_inc(&net->ipv4.fib_num_tclassid_users); 268 268 } 269 269 #endif 270 270 ··· 296 296 297 297 #ifdef CONFIG_IP_ROUTE_CLASSID 298 298 if (((struct fib4_rule *)rule)->tclassid) 299 - net->ipv4.fib_num_tclassid_users--; 299 + atomic_dec(&net->ipv4.fib_num_tclassid_users); 300 300 #endif 301 301 net->ipv4.fib_has_custom_rules = true; 302 302
+2 -2
net/ipv4/fib_semantics.c
··· 220 220 { 221 221 #ifdef CONFIG_IP_ROUTE_CLASSID 222 222 if (fib_nh->nh_tclassid) 223 - net->ipv4.fib_num_tclassid_users--; 223 + atomic_dec(&net->ipv4.fib_num_tclassid_users); 224 224 #endif 225 225 fib_nh_common_release(&fib_nh->nh_common); 226 226 } ··· 632 632 #ifdef CONFIG_IP_ROUTE_CLASSID 633 633 nh->nh_tclassid = cfg->fc_flow; 634 634 if (nh->nh_tclassid) 635 - net->ipv4.fib_num_tclassid_users++; 635 + atomic_inc(&net->ipv4.fib_num_tclassid_users); 636 636 #endif 637 637 #ifdef CONFIG_IP_ROUTE_MULTIPATH 638 638 nh->fib_nh_weight = nh_weight;