aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-16 22:15:23 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-16 22:15:23 -0400
commit6bd64ac0f9c264082241da0db0dcc72a13e672a8 (patch)
treeae8f0e7e20b1ea40d407991ed82d3bd2e1ae3445 /include/linux
parent29e98242783ed3ba569797846a606ba66f781625 (diff)
parentc674ac30c549596295eb0a5af7f4714c0b905b6f (diff)
Merge branch 'stacked_netdevice_locking'
Vlad Yasevich says: ==================== Fix lockdep issues with stacked devices Recent commit dc8eaaa006350d24030502a4521542e74b5cb39f vlan: Fix lockdep warning when vlan dev handle notification attempted to solve lockdep issues with vlans where multiple vlans were stacked. However, the code does not work correctly when the vlan stack is interspersed with other devices in between the vlans. Additionally, similar lockdep issues show up with other devices. This series provides a generic way to solve these issue for any devices that can be stacked. It also addresses the concern for vlan and macvlan devices. I am not sure whether it makes sense to do so for other types like team, vxlan, and bond. Thanks -vlad Since v2: - Remove rcu variants from patch1, since that function is called only under rtnl. - Fix whitespace problems reported by checkpatch Since v1: - Fixed up a goofed-up rebase. * is_vlan_dev() should be bool and that change belongs in patch3. * patch4 should not have any vlan changes in it. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/if_macvlan.h1
-rw-r--r--include/linux/if_vlan.h3
-rw-r--r--include/linux/netdevice.h18
3 files changed, 20 insertions, 2 deletions
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index 7c8b20b120ea..a9a53b12397b 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -56,6 +56,7 @@ struct macvlan_dev {
56 int numqueues; 56 int numqueues;
57 netdev_features_t tap_features; 57 netdev_features_t tap_features;
58 int minor; 58 int minor;
59 int nest_level;
59}; 60};
60 61
61static inline void macvlan_count_rx(const struct macvlan_dev *vlan, 62static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
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 */
74extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); 74extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
75 75
76static inline int is_vlan_dev(struct net_device *dev) 76static 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
164static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) 165static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 20e99efb1ca6..9d4b1f1b6b75 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1144,6 +1144,7 @@ struct net_device_ops {
1144 netdev_tx_t (*ndo_dfwd_start_xmit) (struct sk_buff *skb, 1144 netdev_tx_t (*ndo_dfwd_start_xmit) (struct sk_buff *skb,
1145 struct net_device *dev, 1145 struct net_device *dev,
1146 void *priv); 1146 void *priv);
1147 int (*ndo_get_lock_subclass)(struct net_device *dev);
1147}; 1148};
1148 1149
1149/** 1150/**
@@ -2950,7 +2951,12 @@ static inline void netif_addr_lock(struct net_device *dev)
2950 2951
2951static inline void netif_addr_lock_nested(struct net_device *dev) 2952static inline void netif_addr_lock_nested(struct net_device *dev)
2952{ 2953{
2953 spin_lock_nested(&dev->addr_list_lock, SINGLE_DEPTH_NESTING); 2954 int subclass = SINGLE_DEPTH_NESTING;
2955
2956 if (dev->netdev_ops->ndo_get_lock_subclass)
2957 subclass = dev->netdev_ops->ndo_get_lock_subclass(dev);
2958
2959 spin_lock_nested(&dev->addr_list_lock, subclass);
2954} 2960}
2955 2961
2956static inline void netif_addr_lock_bh(struct net_device *dev) 2962static inline void netif_addr_lock_bh(struct net_device *dev)
@@ -3077,6 +3083,14 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
3077 priv; \ 3083 priv; \
3078 priv = netdev_lower_get_next_private_rcu(dev, &(iter))) 3084 priv = netdev_lower_get_next_private_rcu(dev, &(iter)))
3079 3085
3086void *netdev_lower_get_next(struct net_device *dev,
3087 struct list_head **iter);
3088#define netdev_for_each_lower_dev(dev, ldev, iter) \
3089 for (iter = &(dev)->adj_list.lower, \
3090 ldev = netdev_lower_get_next(dev, &(iter)); \
3091 ldev; \
3092 ldev = netdev_lower_get_next(dev, &(iter)))
3093
3080void *netdev_adjacent_get_private(struct list_head *adj_list); 3094void *netdev_adjacent_get_private(struct list_head *adj_list);
3081void *netdev_lower_get_first_private_rcu(struct net_device *dev); 3095void *netdev_lower_get_first_private_rcu(struct net_device *dev);
3082struct net_device *netdev_master_upper_dev_get(struct net_device *dev); 3096struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
@@ -3092,6 +3106,8 @@ void netdev_upper_dev_unlink(struct net_device *dev,
3092void netdev_adjacent_rename_links(struct net_device *dev, char *oldname); 3106void netdev_adjacent_rename_links(struct net_device *dev, char *oldname);
3093void *netdev_lower_dev_get_private(struct net_device *dev, 3107void *netdev_lower_dev_get_private(struct net_device *dev,
3094 struct net_device *lower_dev); 3108 struct net_device *lower_dev);
3109int dev_get_nest_level(struct net_device *dev,
3110 bool (*type_check)(struct net_device *dev));
3095int skb_checksum_help(struct sk_buff *skb); 3111int skb_checksum_help(struct sk_buff *skb);
3096struct sk_buff *__skb_gso_segment(struct sk_buff *skb, 3112struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
3097 netdev_features_t features, bool tx_path); 3113 netdev_features_t features, bool tx_path);