summaryrefslogtreecommitdiff
path: root/include/linux/netdevice.h
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/netdevice.h
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/netdevice.h')
-rw-r--r--include/linux/netdevice.h18
1 files changed, 17 insertions, 1 deletions
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 {
netdev_tx_t (*ndo_dfwd_start_xmit) (struct sk_buff *skb,
struct net_device *dev,
void *priv);
+ int (*ndo_get_lock_subclass)(struct net_device *dev);
};
/**
@@ -2950,7 +2951,12 @@ static inline void netif_addr_lock(struct net_device *dev)
static inline void netif_addr_lock_nested(struct net_device *dev)
{
- spin_lock_nested(&dev->addr_list_lock, SINGLE_DEPTH_NESTING);
+ int subclass = SINGLE_DEPTH_NESTING;
+
+ if (dev->netdev_ops->ndo_get_lock_subclass)
+ subclass = dev->netdev_ops->ndo_get_lock_subclass(dev);
+
+ spin_lock_nested(&dev->addr_list_lock, subclass);
}
static 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,
priv; \
priv = netdev_lower_get_next_private_rcu(dev, &(iter)))
+void *netdev_lower_get_next(struct net_device *dev,
+ struct list_head **iter);
+#define netdev_for_each_lower_dev(dev, ldev, iter) \
+ for (iter = &(dev)->adj_list.lower, \
+ ldev = netdev_lower_get_next(dev, &(iter)); \
+ ldev; \
+ ldev = netdev_lower_get_next(dev, &(iter)))
+
void *netdev_adjacent_get_private(struct list_head *adj_list);
void *netdev_lower_get_first_private_rcu(struct net_device *dev);
struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
@@ -3092,6 +3106,8 @@ void netdev_upper_dev_unlink(struct net_device *dev,
void netdev_adjacent_rename_links(struct net_device *dev, char *oldname);
void *netdev_lower_dev_get_private(struct net_device *dev,
struct net_device *lower_dev);
+int dev_get_nest_level(struct net_device *dev,
+ bool (*type_check)(struct net_device *dev));
int skb_checksum_help(struct sk_buff *skb);
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path);