ipv6 sit: Optimize multiple unregistration
authorEric Dumazet <eric.dumazet@gmail.com>
Wed, 28 Oct 2009 04:37:43 +0000 (04:37 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 29 Oct 2009 08:13:51 +0000 (01:13 -0700)
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>
net/ipv6/sit.c

index b6b16264b3051d12e3b652275523e108fadb7d0f..2362a3397e91e40fd0c2907bd55fbd6512ea1d30 100644 (file)
@@ -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);
 }