diff options
author | David S. Miller <davem@davemloft.net> | 2017-09-19 16:32:24 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-09-19 16:32:24 -0700 |
commit | 8ca712c373a462cfa1b62272870b6c2c74aa83f9 (patch) | |
tree | 484826d20103aa296586883918c1ba6a3e74ef0b /net/ipv4/ip_vti.c | |
parent | net_sched: no need to free qdisc in RCU callback (diff) | |
parent | ipv4: speedup ipv6 tunnels dismantle (diff) | |
download | linux-dev-8ca712c373a462cfa1b62272870b6c2c74aa83f9.tar.xz linux-dev-8ca712c373a462cfa1b62272870b6c2c74aa83f9.zip |
Merge branch 'net-speedup-netns-create-delete-time'
Eric Dumazet says:
====================
net: speedup netns create/delete time
When rate of netns creation/deletion is high enough,
we observe softlockups in cleanup_net() caused by huge list
of netns and way too many rcu_barrier() calls.
This patch series does some optimizations in kobject,
and add batching to tunnels so that netns dismantles are
less costly.
IPv6 addrlabels also get a per netns list, and tcp_metrics
also benefit from batch flushing.
This gives me one order of magnitude gain.
(~50 ms -> ~5 ms for one netns create/delete pair)
Tested:
for i in `seq 1 40`
do
(for j in `seq 1 100` ; do unshare -n /bin/true >/dev/null ; done) &
done
wait ; grep net_namespace /proc/slabinfo
Before patch series :
$ time ./add_del_unshare.sh
net_namespace 116 258 5504 1 2 : tunables 8 4 0 : slabdata 116 258 0
real 3m24.910s
user 0m0.747s
sys 0m43.162s
After :
$ time ./add_del_unshare.sh
net_namespace 135 291 5504 1 2 : tunables 8 4 0 : slabdata 135 291 0
real 0m22.117s
user 0m0.728s
sys 0m35.328s
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | net/ipv4/ip_vti.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 5ed63d250950..02d70ca99db1 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -452,15 +452,14 @@ static int __net_init vti_init_net(struct net *net) return 0; } -static void __net_exit vti_exit_net(struct net *net) +static void __net_exit vti_exit_batch_net(struct list_head *list_net) { - struct ip_tunnel_net *itn = net_generic(net, vti_net_id); - ip_tunnel_delete_net(itn, &vti_link_ops); + ip_tunnel_delete_nets(list_net, vti_net_id, &vti_link_ops); } static struct pernet_operations vti_net_ops = { .init = vti_init_net, - .exit = vti_exit_net, + .exit_batch = vti_exit_batch_net, .id = &vti_net_id, .size = sizeof(struct ip_tunnel_net), }; |