vlan: remove one synchronize_net() call
authorEric Dumazet <eric.dumazet@gmail.com>
Mon, 9 May 2011 04:40:44 +0000 (04:40 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 May 2011 18:41:41 +0000 (11:41 -0700)
At VLAN dismantle phase, unregister_vlan_dev() makes one
synchronize_net() call after vlan_group_set_device(grp, vlan_id, NULL).

This call can be safely removed because we are calling
unregister_netdevice_queue() to queue device for deletion, and this
process needs at least one rcu grace period to complete.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Ben Greear <greearb@candelatech.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Jesse Gross <jesse@nicira.com>
Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Acked-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/if_vlan.h
net/8021q/vlan.c

index 546d9d3..290bd8a 100644 (file)
@@ -86,7 +86,6 @@ struct vlan_group {
                                            * the vlan is attached to.
                                            */
        unsigned int            nr_vlans;
-       int                     killall;
        struct hlist_node       hlist;  /* linked list */
        struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
        struct rcu_head         rcu;
index 969e700..718d635 100644 (file)
@@ -120,9 +120,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
        grp->nr_vlans--;
 
        vlan_group_set_device(grp, vlan_id, NULL);
-       if (!grp->killall)
-               synchronize_net();
-
+       /* Because unregister_netdevice_queue() makes sure at least one rcu
+        * grace period is respected before device freeing,
+        * we dont need to call synchronize_net() here.
+        */
        unregister_netdevice_queue(dev, head);
 
        /* If the group is now empty, kill off the group. */
@@ -478,9 +479,6 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
                if (dev->reg_state != NETREG_UNREGISTERING)
                        break;
 
-               /* Delete all VLANs for this dev. */
-               grp->killall = 1;
-
                for (i = 0; i < VLAN_N_VID; i++) {
                        vlandev = vlan_group_get_device(grp, i);
                        if (!vlandev)