|
@@ -493,48 +493,10 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int vlan_calculate_locking_subclass(struct net_device *real_dev)
|
|
|
-{
|
|
|
- int subclass = 0;
|
|
|
-
|
|
|
- while (is_vlan_dev(real_dev)) {
|
|
|
- subclass++;
|
|
|
- real_dev = vlan_dev_priv(real_dev)->real_dev;
|
|
|
- }
|
|
|
-
|
|
|
- return subclass;
|
|
|
-}
|
|
|
-
|
|
|
-static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
|
|
|
-{
|
|
|
- int err = 0, subclass;
|
|
|
-
|
|
|
- subclass = vlan_calculate_locking_subclass(to);
|
|
|
-
|
|
|
- spin_lock_nested(&to->addr_list_lock, subclass);
|
|
|
- err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
|
|
|
- if (!err)
|
|
|
- __dev_set_rx_mode(to);
|
|
|
- spin_unlock(&to->addr_list_lock);
|
|
|
-}
|
|
|
-
|
|
|
-static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
|
|
|
-{
|
|
|
- int err = 0, subclass;
|
|
|
-
|
|
|
- subclass = vlan_calculate_locking_subclass(to);
|
|
|
-
|
|
|
- spin_lock_nested(&to->addr_list_lock, subclass);
|
|
|
- err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
|
|
|
- if (!err)
|
|
|
- __dev_set_rx_mode(to);
|
|
|
- spin_unlock(&to->addr_list_lock);
|
|
|
-}
|
|
|
-
|
|
|
static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
|
|
|
{
|
|
|
- vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
|
|
|
- vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
|
|
|
+ dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
|
|
|
+ dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -562,6 +524,11 @@ static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass)
|
|
|
netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass);
|
|
|
}
|
|
|
|
|
|
+static int vlan_dev_get_lock_subclass(struct net_device *dev)
|
|
|
+{
|
|
|
+ return vlan_dev_priv(dev)->nest_level;
|
|
|
+}
|
|
|
+
|
|
|
static const struct header_ops vlan_header_ops = {
|
|
|
.create = vlan_dev_hard_header,
|
|
|
.rebuild = vlan_dev_rebuild_header,
|
|
@@ -597,7 +564,6 @@ static const struct net_device_ops vlan_netdev_ops;
|
|
|
static int vlan_dev_init(struct net_device *dev)
|
|
|
{
|
|
|
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
|
|
|
- int subclass = 0;
|
|
|
|
|
|
netif_carrier_off(dev);
|
|
|
|
|
@@ -646,8 +612,7 @@ static int vlan_dev_init(struct net_device *dev)
|
|
|
|
|
|
SET_NETDEV_DEVTYPE(dev, &vlan_type);
|
|
|
|
|
|
- subclass = vlan_calculate_locking_subclass(dev);
|
|
|
- vlan_dev_set_lockdep_class(dev, subclass);
|
|
|
+ vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev));
|
|
|
|
|
|
vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
|
|
|
if (!vlan_dev_priv(dev)->vlan_pcpu_stats)
|
|
@@ -819,6 +784,7 @@ static const struct net_device_ops vlan_netdev_ops = {
|
|
|
.ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup,
|
|
|
#endif
|
|
|
.ndo_fix_features = vlan_dev_fix_features,
|
|
|
+ .ndo_get_lock_subclass = vlan_dev_get_lock_subclass,
|
|
|
};
|
|
|
|
|
|
void vlan_setup(struct net_device *dev)
|