diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-10-28 04:37:43 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-29 01:13:51 -0700 |
commit | 62808f91237181dbac74c2b5be4fa92adfbbbe40 (patch) | |
tree | 8f477adb2400764425f0e3c32570c3d1656c7c5c /net/ipv6/sit.c | |
parent | d17fa6fa81d9be6d2dc69aedfabecf904210cbf4 (diff) | |
download | lwn-62808f91237181dbac74c2b5be4fa92adfbbbe40.tar.gz lwn-62808f91237181dbac74c2b5be4fa92adfbbbe40.zip |
ipv6 sit: Optimize multiple unregistration
Speedup module unloading by factorizing synchronize_rcu() calls
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b6b16264b305..2362a3397e91 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1145,16 +1145,19 @@ static struct xfrm_tunnel sit_handler = { .priority = 1, }; -static void sit_destroy_tunnels(struct sit_net *sitn) +static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) { int prio; for (prio = 1; prio < 4; prio++) { int h; for (h = 0; h < HASH_SIZE; h++) { - struct ip_tunnel *t; - while ((t = sitn->tunnels[prio][h]) != NULL) - unregister_netdevice(t->dev); + struct ip_tunnel *t = sitn->tunnels[prio][h]; + + while (t != NULL) { + unregister_netdevice_queue(t->dev, head); + t = t->next; + } } } } @@ -1208,11 +1211,13 @@ err_alloc: static void sit_exit_net(struct net *net) { struct sit_net *sitn; + LIST_HEAD(list); sitn = net_generic(net, sit_net_id); rtnl_lock(); - sit_destroy_tunnels(sitn); - unregister_netdevice(sitn->fb_tunnel_dev); + sit_destroy_tunnels(sitn, &list); + unregister_netdevice_queue(sitn->fb_tunnel_dev, &list); + unregister_netdevice_many(&list); rtnl_unlock(); kfree(sitn); } |