net: Fix high overhead of vlan sub-device teardown.
[deliverable/linux.git] / net / 8021q / vlan.c
index 64c6bed4a3d3aa4545f596a1a146f1d053db949c..98a30a5b866472b7421f5394636934bc23ec7f94 100644 (file)
@@ -413,7 +413,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
                        vlan_transfer_features(dev, vlandev);
                break;
 
-       case NETDEV_DOWN:
+       case NETDEV_DOWN: {
+               struct net_device *tmp;
+               LIST_HEAD(close_list);
+
                if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
                        vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
 
@@ -425,11 +428,18 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 
                        vlan = vlan_dev_priv(vlandev);
                        if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
-                               dev_change_flags(vlandev, flgs & ~IFF_UP);
+                               list_add(&vlandev->close_list, &close_list);
+               }
+
+               dev_close_many(&close_list, false);
+
+               list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) {
                        netif_stacked_transfer_operstate(dev, vlandev);
+                       list_del_init(&vlandev->close_list);
                }
+               list_del(&close_list);
                break;
-
+       }
        case NETDEV_UP:
                /* Put all VLANs for this dev in the up state too.  */
                vlan_group_for_each_dev(grp, i, vlandev) {
This page took 0.02654 seconds and 5 git commands to generate.