From 753d525a08f2e18d50da9a909d48ecb7596683b3 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:48:04 +0300 Subject: net: Convert inet6_net_ops init method initializes sysctl defaults, allocates percpu arrays and creates /proc entries. exit method reverts the above. There are no pernet_operations, which are interested in the above entities of foreign net namespace, so inet6_net_ops are able to be marked as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c1e292db04db..dbbe04018813 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -857,6 +857,7 @@ static void __net_exit inet6_net_exit(struct net *net) static struct pernet_operations inet6_net_ops = { .init = inet6_net_init, .exit = inet6_net_exit, + .async = true, }; static const struct ipv6_stub ipv6_stub_impl = { -- cgit v1.2.3 From 9c537ca1554e5d7db69a3b606801a2101e02edda Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:48:14 +0300 Subject: net: Convert cfg80211_pernet_ops This patch finishes converting pernet_operations registered in net/wireless directory. These pernet_operations have only exit method, which moves devices to init_net. This action is not pernet_operations-specific, and function cfg80211_switch_netns() may be called all time during the system life. All necessary protection against concurrent cfg80211_pernet_exit() is made by rtnl_lock(). So, cfg80211_pernet_ops is able to be marked as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/wireless/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/wireless/core.c b/net/wireless/core.c index a6f3cac8c640..670aa229168a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1340,6 +1340,7 @@ static void __net_exit cfg80211_pernet_exit(struct net *net) static struct pernet_operations cfg80211_pernet_ops = { .exit = cfg80211_pernet_exit, + .async = true, }; static int __init cfg80211_init(void) -- cgit v1.2.3 From b01a59a4884ed2d95b8db4741e552a689c18989b Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:48:37 +0300 Subject: net: Convert ip6mr_net_ops These pernet_operations create and destroy /proc entries, populate and depopulate net::rules_ops and multiroute table. All the structures are pernet, and they are not touched by foreign net pernet_operations. So, it's possible to mark them async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/ip6mr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 9f6cace9c817..295eb5ecaee5 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1397,6 +1397,7 @@ static void __net_exit ip6mr_net_exit(struct net *net) static struct pernet_operations ip6mr_net_ops = { .init = ip6mr_net_init, .exit = ip6mr_net_exit, + .async = true, }; int __init ip6_mr_init(void) -- cgit v1.2.3 From 1a2e93329dd413585798c122aac0607093b2d379 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:48:57 +0300 Subject: net: Convert icmpv6_sk_ops, ndisc_net_ops and igmp6_net_ops These pernet_operations create and destroy net::ipv6.icmp_sk socket, used to send ICMP or error reply. Nobody can dereference the socket to handle a packet before net is initialized, as there is no routing; nobody can do that in parallel with exit, as all of devices are moved to init_net or destroyed and there are no packets it-flight. So, it's possible to mark these pernet_operations as async. The same for ndisc_net_ops and for igmp6_net_ops. The last one also creates and destroys /proc entries. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/icmp.c | 1 + net/ipv6/mcast.c | 1 + net/ipv6/ndisc.c | 1 + 3 files changed, 3 insertions(+) diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 6ae5dd3f4d0d..4fa4f1b150a4 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -997,6 +997,7 @@ static void __net_exit icmpv6_sk_exit(struct net *net) static struct pernet_operations icmpv6_sk_ops = { .init = icmpv6_sk_init, .exit = icmpv6_sk_exit, + .async = true, }; int __init icmpv6_init(void) diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 9b9d2ff01b35..d9bb933dd5c4 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2997,6 +2997,7 @@ static void __net_exit igmp6_net_exit(struct net *net) static struct pernet_operations igmp6_net_ops = { .init = igmp6_net_init, .exit = igmp6_net_exit, + .async = true, }; int __init igmp6_init(void) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f61a5b613b52..0a19ce3a6f7f 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1882,6 +1882,7 @@ static void __net_exit ndisc_net_exit(struct net *net) static struct pernet_operations ndisc_net_ops = { .init = ndisc_net_init, .exit = ndisc_net_exit, + .async = true, }; int __init ndisc_init(void) -- cgit v1.2.3 From 509114112d0b71997dbe58d4f2976eeddf8eacc4 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:49:10 +0300 Subject: net: Convert raw6_net_ops, udplite6_net_ops, ipv6_proc_ops, if6_proc_net_ops and ip6_route_net_late_ops These pernet_operations create and destroy /proc entries and safely may be converted and safely may be mark as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 1 + net/ipv6/proc.c | 1 + net/ipv6/raw.c | 1 + net/ipv6/route.c | 2 ++ 4 files changed, 5 insertions(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8c17f8d8d5d9..4facfe0b1888 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4257,6 +4257,7 @@ static void __net_exit if6_proc_net_exit(struct net *net) static struct pernet_operations if6_proc_net_ops = { .init = if6_proc_net_init, .exit = if6_proc_net_exit, + .async = true, }; int __init if6_proc_init(void) diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index b67814242f78..b8858c546f41 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -343,6 +343,7 @@ static void __net_exit ipv6_proc_exit_net(struct net *net) static struct pernet_operations ipv6_proc_ops = { .init = ipv6_proc_init_net, .exit = ipv6_proc_exit_net, + .async = true, }; int __init ipv6_misc_proc_init(void) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 4c25339b1984..10a4ac4933b7 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -1332,6 +1332,7 @@ static void __net_exit raw6_exit_net(struct net *net) static struct pernet_operations raw6_net_ops = { .init = raw6_init_net, .exit = raw6_exit_net, + .async = true, }; int __init raw6_proc_init(void) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index f0baae26db8f..1be84ef23f43 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4972,6 +4972,7 @@ static void __net_exit ip6_route_net_exit_late(struct net *net) static struct pernet_operations ip6_route_net_ops = { .init = ip6_route_net_init, .exit = ip6_route_net_exit, + .async = true, }; static int __net_init ipv6_inetpeer_init(struct net *net) @@ -5002,6 +5003,7 @@ static struct pernet_operations ipv6_inetpeer_ops = { static struct pernet_operations ip6_route_net_late_ops = { .init = ip6_route_net_init_late, .exit = ip6_route_net_exit_late, + .async = true, }; static struct notifier_block ip6_route_dev_notifier = { -- cgit v1.2.3 From 85ca51b2a23969dccb5abff31eb54560db8195ca Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:49:20 +0300 Subject: net: Convert ipv6_inetpeer_ops net->ipv6.peers is dereferenced in three places via inet_getpeer_v6(), and it's used to handle skb. All the users of inet_getpeer_v6() do not look like be able to be called from foreign net pernet_operations, so we may mark them as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/route.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1be84ef23f43..aa709b644945 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4998,6 +4998,7 @@ static void __net_exit ipv6_inetpeer_exit(struct net *net) static struct pernet_operations ipv6_inetpeer_ops = { .init = ipv6_inetpeer_init, .exit = ipv6_inetpeer_exit, + .async = true, }; static struct pernet_operations ip6_route_net_late_ops = { -- cgit v1.2.3 From 7b7dd180b85b9c39c426cfaade73f7d0409c7f85 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:49:31 +0300 Subject: net: Convert fib6_rules_net_ops These pernet_operations register and unregister net::ipv6.fib6_rules_ops, which are used for routing. It looks like there are no pernet_operations, which send ipv6 packages to another net, so we are able to mark them as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/fib6_rules.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index b240f24a6e52..95a2c9e8699a 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -368,6 +368,7 @@ static void __net_exit fib6_rules_net_exit(struct net *net) static struct pernet_operations fib6_rules_net_ops = { .init = fib6_rules_net_init, .exit = fib6_rules_net_exit, + .async = true, }; int __init fib6_rules_init(void) -- cgit v1.2.3 From fef65a2c6c3417fcf2fb0bebd8c27355d1b14a12 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:49:40 +0300 Subject: net: Convert tcpv6_net_ops These pernet_operations create and destroy net::ipv6.tcp_sk socket, which is used in tcp_v6_send_response() only. It looks like foreign pernet_operations don't want to set ipv6 connection inside destroyed net, so this socket may be created in destroyed in parallel with anything else. inet_twsk_purge() is also safe for that, as described in patch for tcp_sk_ops. So, it's possible to mark them as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 883df0ad5bfe..5425d7b100ee 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -2007,6 +2007,7 @@ static struct pernet_operations tcpv6_net_ops = { .init = tcpv6_net_init, .exit = tcpv6_net_exit, .exit_batch = tcpv6_net_exit_batch, + .async = true, }; int __init tcpv6_init(void) -- cgit v1.2.3 From 58708caef56b04da2c91d6aaba49c783f22055c2 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:49:49 +0300 Subject: net: Convert ipv6_sysctl_net_ops These pernet_operations create and destroy sysctl tables. They are not touched by another net pernet_operations. So, it's possible to execute them in parallel with others. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/sysctl_net_ipv6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index a789a8ac6a64..262f791f1b9b 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -251,6 +251,7 @@ static void __net_exit ipv6_sysctl_net_exit(struct net *net) static struct pernet_operations ipv6_sysctl_net_ops = { .init = ipv6_sysctl_net_init, .exit = ipv6_sysctl_net_exit, + .async = true, }; static struct ctl_table_header *ip6_header; -- cgit v1.2.3 From ac34cb6c0c4d327d69e588d7a42bbc6428e2fdfd Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:49:59 +0300 Subject: net: Convert ping_v6_net_ops These pernet_operations only register and unregister /proc entries, so it's possible to mark them async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/ping.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index d12c55dad7d1..318c6e914234 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -240,6 +240,7 @@ static void __net_init ping_v6_proc_exit_net(struct net *net) static struct pernet_operations ping_v6_net_ops = { .init = ping_v6_proc_init_net, .exit = ping_v6_proc_exit_net, + .async = true, }; #endif -- cgit v1.2.3 From a7852a76f414f69631ed3adc4b001c633829306d Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:50:09 +0300 Subject: net: Convert ip6_flowlabel_net_ops These pernet_operations create and destroy /proc entries. ip6_fl_purge() makes almost the same actions as timer ip6_fl_gc_timer does, and as it can be executed in parallel with ip6_fl_purge(), two parallel ip6_fl_purge() may be executed. So, we can mark it async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/ip6_flowlabel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 3dab664ff503..6ddf52282894 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -873,6 +873,7 @@ static void __net_exit ip6_flowlabel_net_exit(struct net *net) static struct pernet_operations ip6_flowlabel_net_ops = { .init = ip6_flowlabel_proc_init, .exit = ip6_flowlabel_net_exit, + .async = true, }; int ip6_flowlabel_init(void) -- cgit v1.2.3 From b489141369f78ead6ed540cff29ac1974852cd7f Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:50:18 +0300 Subject: net: Convert xfrm6_net_ops These pernet_operations create sysctl tables and initialize net::xfrm.xfrm6_dst_ops used for routing. It doesn't look like another pernet_operations send ipv6 packets to foreign net namespaces, so it should be safe to mark the pernet_operations as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/xfrm6_policy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 09fb44ee3b45..88cd0c90fa81 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -395,6 +395,7 @@ static void __net_exit xfrm6_net_exit(struct net *net) static struct pernet_operations xfrm6_net_ops = { .init = xfrm6_net_init, .exit = xfrm6_net_exit, + .async = true, }; int __init xfrm6_init(void) -- cgit v1.2.3 From d16784d9fb2a91e96374df7cb689f52cef55371b Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:50:28 +0300 Subject: net: Convert fib6_net_ops, ipv6_addr_label_ops and ip6_segments_ops These pernet_operations register and unregister tables and lists for packets forwarding. All of the entities are per-net. Init methods makes simple initializations, and since net is not visible for foreigners at the time it is working, it can't race with anything. Exit method is executed when there are only local devices, and there mustn't be packets in-flight. Also, it looks like no one pernet_operations want to send ipv6 packets to foreign net. The same reasons are for ipv6_addr_label_ops and ip6_segments_ops. So, we are able to mark all them as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/addrlabel.c | 1 + net/ipv6/ip6_fib.c | 1 + net/ipv6/seg6.c | 1 + 3 files changed, 3 insertions(+) diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 1d6ced37ad71..ba2e63633370 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c @@ -344,6 +344,7 @@ static void __net_exit ip6addrlbl_net_exit(struct net *net) static struct pernet_operations ipv6_addr_label_ops = { .init = ip6addrlbl_net_init, .exit = ip6addrlbl_net_exit, + .async = true, }; int __init ipv6_addr_label_init(void) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 92b8d8c75eed..cab95cf3b39f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -2160,6 +2160,7 @@ static void fib6_net_exit(struct net *net) static struct pernet_operations fib6_net_ops = { .init = fib6_net_init, .exit = fib6_net_exit, + .async = true, }; int __init fib6_init(void) diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c index 7f5621d09571..c3f13c3bd8a9 100644 --- a/net/ipv6/seg6.c +++ b/net/ipv6/seg6.c @@ -395,6 +395,7 @@ static void __net_exit seg6_net_exit(struct net *net) static struct pernet_operations ip6_segments_ops = { .init = seg6_net_init, .exit = seg6_net_exit, + .async = true, }; static const struct genl_ops seg6_genl_ops[] = { -- cgit v1.2.3 From 5fc094f5b8c9b8e5012b7ccf303be3b123563a58 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:50:37 +0300 Subject: net: Convert ip6_frags_ops Exit methods calls inet_frags_exit_net() with global ip6_frags as argument. So, after we make the pernet_operations async, a pair of exit methods may be called to iterate this hash table. Since there is inet_frag_worker(), which already may work in parallel with inet_frags_exit_net(), and it can make the same cleanup, that inet_frags_exit_net() does, it's safe. So we may mark these pernet_operations as async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv6/reassembly.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index afbc000ad4f2..b5da69c83123 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -733,6 +733,7 @@ static void __net_exit ipv6_frags_exit_net(struct net *net) static struct pernet_operations ip6_frags_ops = { .init = ipv6_frags_init_net, .exit = ipv6_frags_exit_net, + .async = true, }; int __init ipv6_frag_init(void) -- cgit v1.2.3 From 4d6b80762b9384db3281f792a71746b388f395be Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:50:45 +0300 Subject: net: Convert ip_tables_net_ops, udplite6_net_ops and xt_net_ops ip_tables_net_ops and udplite6_net_ops create and destroy /proc entries. xt_net_ops does nothing. So, we are able to mark them async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_tables.c | 1 + net/ipv6/udplite.c | 1 + net/netfilter/x_tables.c | 1 + 3 files changed, 3 insertions(+) diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 9a71f3149507..39a7cf9160e6 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1911,6 +1911,7 @@ static void __net_exit ip_tables_net_exit(struct net *net) static struct pernet_operations ip_tables_net_ops = { .init = ip_tables_net_init, .exit = ip_tables_net_exit, + .async = true, }; static int __init ip_tables_init(void) diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 14ae32bb1f3d..f3839780dc31 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c @@ -123,6 +123,7 @@ static void __net_exit udplite6_proc_exit_net(struct net *net) static struct pernet_operations udplite6_net_ops = { .init = udplite6_proc_init_net, .exit = udplite6_proc_exit_net, + .async = true, }; int __init udplite6_proc_init(void) diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 2f685ee1f9c8..a6a435d7c8f4 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1765,6 +1765,7 @@ static void __net_exit xt_net_exit(struct net *net) static struct pernet_operations xt_net_ops = { .init = xt_net_init, .exit = xt_net_exit, + .async = true, }; static int __init xt_init(void) -- cgit v1.2.3 From da349fad8045cc44cd9b1752b0e2d943df62cabf Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 19 Feb 2018 11:50:54 +0300 Subject: net: Convert iptable_filter_net_ops These pernet_operations register and unregister net::ipv4.iptable_filter table. Since there are no packets in-flight at the time of exit method is working, iptables rules should not be touched. Also, pernet_operations should not send ipv4 packets each other. So, it's safe to mark them async. Signed-off-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/ipv4/netfilter/iptable_filter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 9ac92ea7b93c..c1c136a93911 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c @@ -87,6 +87,7 @@ static void __net_exit iptable_filter_net_exit(struct net *net) static struct pernet_operations iptable_filter_net_ops = { .init = iptable_filter_net_init, .exit = iptable_filter_net_exit, + .async = true, }; static int __init iptable_filter_init(void) -- cgit v1.2.3