diff options
| -rw-r--r-- | include/linux/if_vlan.h | 3 | ||||
| -rw-r--r-- | net/8021q/vlan.c | 1 | ||||
| -rw-r--r-- | net/8021q/vlan_dev.c | 52 | ||||
| -rw-r--r-- | net/core/dev.c | 1 |
4 files changed, 12 insertions, 45 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 13bbbde00e68..724bde8477b2 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
| @@ -73,7 +73,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) | |||
| 73 | /* found in socket.c */ | 73 | /* found in socket.c */ |
| 74 | extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); | 74 | extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); |
| 75 | 75 | ||
| 76 | static inline int is_vlan_dev(struct net_device *dev) | 76 | static inline bool is_vlan_dev(struct net_device *dev) |
| 77 | { | 77 | { |
| 78 | return dev->priv_flags & IFF_802_1Q_VLAN; | 78 | return dev->priv_flags & IFF_802_1Q_VLAN; |
| 79 | } | 79 | } |
| @@ -159,6 +159,7 @@ struct vlan_dev_priv { | |||
| 159 | #ifdef CONFIG_NET_POLL_CONTROLLER | 159 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 160 | struct netpoll *netpoll; | 160 | struct netpoll *netpoll; |
| 161 | #endif | 161 | #endif |
| 162 | unsigned int nest_level; | ||
| 162 | }; | 163 | }; |
| 163 | 164 | ||
| 164 | static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) | 165 | static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 175273f38cb1..44ebd5c2cd4a 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -169,6 +169,7 @@ int register_vlan_dev(struct net_device *dev) | |||
| 169 | if (err < 0) | 169 | if (err < 0) |
| 170 | goto out_uninit_mvrp; | 170 | goto out_uninit_mvrp; |
| 171 | 171 | ||
| 172 | vlan->nest_level = dev_get_nest_level(real_dev, is_vlan_dev) + 1; | ||
| 172 | err = register_netdevice(dev); | 173 | err = register_netdevice(dev); |
| 173 | if (err < 0) | 174 | if (err < 0) |
| 174 | goto out_uninit_mvrp; | 175 | goto out_uninit_mvrp; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 733ec283ed1b..019efb79708f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -493,48 +493,10 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) | |||
| 493 | } | 493 | } |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | static int vlan_calculate_locking_subclass(struct net_device *real_dev) | ||
| 497 | { | ||
| 498 | int subclass = 0; | ||
| 499 | |||
| 500 | while (is_vlan_dev(real_dev)) { | ||
| 501 | subclass++; | ||
| 502 | real_dev = vlan_dev_priv(real_dev)->real_dev; | ||
| 503 | } | ||
| 504 | |||
| 505 | return subclass; | ||
| 506 | } | ||
| 507 | |||
| 508 | static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from) | ||
| 509 | { | ||
| 510 | int err = 0, subclass; | ||
| 511 | |||
| 512 | subclass = vlan_calculate_locking_subclass(to); | ||
| 513 | |||
| 514 | spin_lock_nested(&to->addr_list_lock, subclass); | ||
| 515 | err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); | ||
| 516 | if (!err) | ||
| 517 | __dev_set_rx_mode(to); | ||
| 518 | spin_unlock(&to->addr_list_lock); | ||
| 519 | } | ||
| 520 | |||
| 521 | static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from) | ||
| 522 | { | ||
| 523 | int err = 0, subclass; | ||
| 524 | |||
| 525 | subclass = vlan_calculate_locking_subclass(to); | ||
| 526 | |||
| 527 | spin_lock_nested(&to->addr_list_lock, subclass); | ||
| 528 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); | ||
| 529 | if (!err) | ||
| 530 | __dev_set_rx_mode(to); | ||
| 531 | spin_unlock(&to->addr_list_lock); | ||
| 532 | } | ||
| 533 | |||
| 534 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) | 496 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) |
| 535 | { | 497 | { |
| 536 | vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); | 498 | dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); |
| 537 | vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); | 499 | dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); |
| 538 | } | 500 | } |
| 539 | 501 | ||
| 540 | /* | 502 | /* |
| @@ -562,6 +524,11 @@ static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass) | |||
| 562 | netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass); | 524 | netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass); |
| 563 | } | 525 | } |
| 564 | 526 | ||
| 527 | static int vlan_dev_get_lock_subclass(struct net_device *dev) | ||
| 528 | { | ||
| 529 | return vlan_dev_priv(dev)->nest_level; | ||
| 530 | } | ||
| 531 | |||
| 565 | static const struct header_ops vlan_header_ops = { | 532 | static const struct header_ops vlan_header_ops = { |
| 566 | .create = vlan_dev_hard_header, | 533 | .create = vlan_dev_hard_header, |
| 567 | .rebuild = vlan_dev_rebuild_header, | 534 | .rebuild = vlan_dev_rebuild_header, |
| @@ -597,7 +564,6 @@ static const struct net_device_ops vlan_netdev_ops; | |||
| 597 | static int vlan_dev_init(struct net_device *dev) | 564 | static int vlan_dev_init(struct net_device *dev) |
| 598 | { | 565 | { |
| 599 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 566 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; |
| 600 | int subclass = 0; | ||
| 601 | 567 | ||
| 602 | netif_carrier_off(dev); | 568 | netif_carrier_off(dev); |
| 603 | 569 | ||
| @@ -646,8 +612,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 646 | 612 | ||
| 647 | SET_NETDEV_DEVTYPE(dev, &vlan_type); | 613 | SET_NETDEV_DEVTYPE(dev, &vlan_type); |
| 648 | 614 | ||
| 649 | subclass = vlan_calculate_locking_subclass(dev); | 615 | vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); |
| 650 | vlan_dev_set_lockdep_class(dev, subclass); | ||
| 651 | 616 | ||
| 652 | vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); | 617 | vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); |
| 653 | if (!vlan_dev_priv(dev)->vlan_pcpu_stats) | 618 | if (!vlan_dev_priv(dev)->vlan_pcpu_stats) |
| @@ -819,6 +784,7 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
| 819 | .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, | 784 | .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, |
| 820 | #endif | 785 | #endif |
| 821 | .ndo_fix_features = vlan_dev_fix_features, | 786 | .ndo_fix_features = vlan_dev_fix_features, |
| 787 | .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, | ||
| 822 | }; | 788 | }; |
| 823 | 789 | ||
| 824 | void vlan_setup(struct net_device *dev) | 790 | void vlan_setup(struct net_device *dev) |
diff --git a/net/core/dev.c b/net/core/dev.c index 6ee3ac25ed72..2b872bfbd172 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -5287,7 +5287,6 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
| 5287 | if (ops->ndo_set_rx_mode) | 5287 | if (ops->ndo_set_rx_mode) |
| 5288 | ops->ndo_set_rx_mode(dev); | 5288 | ops->ndo_set_rx_mode(dev); |
| 5289 | } | 5289 | } |
| 5290 | EXPORT_SYMBOL(__dev_set_rx_mode); | ||
| 5291 | 5290 | ||
| 5292 | void dev_set_rx_mode(struct net_device *dev) | 5291 | void dev_set_rx_mode(struct net_device *dev) |
| 5293 | { | 5292 | { |
