aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2016-08-12 10:10:33 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-13 18:15:54 -0400
commit952fcfd08c8109951622579d0ae7b9cd6cafd688 (patch)
tree16e787138d3da28899e3a0028962928c79a4af07
parente20038724552cd05e351cd7d7526d646953d26b7 (diff)
net: remove type_check from dev_get_nest_level()
The idea for type_check in dev_get_nest_level() was to count the number of nested devices of the same type (currently, only macvlan or vlan devices). This prevented the false positive lockdep warning on configurations such as: eth0 <--- macvlan0 <--- vlan0 <--- macvlan1 However, this doesn't prevent a warning on a configuration such as: eth0 <--- macvlan0 <--- vlan0 eth1 <--- vlan1 <--- macvlan1 In this case, all the locks end up with a nesting subclass of 1, so lockdep thinks that there is still a deadlock: - in the first case we have (macvlan_netdev_addr_lock_key, 1) and then take (vlan_netdev_xmit_lock_key, 1) - in the second case, we have (vlan_netdev_xmit_lock_key, 1) and then take (macvlan_netdev_addr_lock_key, 1) By removing the linktype check in dev_get_nest_level() and always incrementing the nesting depth, lockdep considers this configuration valid. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/macsec.c2
-rw-r--r--drivers/net/macvlan.c2
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--net/8021q/vlan.c2
-rw-r--r--net/core/dev.c10
5 files changed, 7 insertions, 12 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 2043e8c97a81..351e701eb043 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3201,7 +3201,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
3201 3201
3202 dev_hold(real_dev); 3202 dev_hold(real_dev);
3203 3203
3204 macsec->nest_level = dev_get_nest_level(real_dev, netif_is_macsec) + 1; 3204 macsec->nest_level = dev_get_nest_level(real_dev) + 1;
3205 netdev_lockdep_set_classes(dev); 3205 netdev_lockdep_set_classes(dev);
3206 lockdep_set_class_and_subclass(&dev->addr_list_lock, 3206 lockdep_set_class_and_subclass(&dev->addr_list_lock,
3207 &macsec_netdev_addr_lock_key, 3207 &macsec_netdev_addr_lock_key,
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index cd9b53834bf6..3234fcdea317 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1315,7 +1315,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
1315 vlan->dev = dev; 1315 vlan->dev = dev;
1316 vlan->port = port; 1316 vlan->port = port;
1317 vlan->set_features = MACVLAN_FEATURES; 1317 vlan->set_features = MACVLAN_FEATURES;
1318 vlan->nest_level = dev_get_nest_level(lowerdev, netif_is_macvlan) + 1; 1318 vlan->nest_level = dev_get_nest_level(lowerdev) + 1;
1319 1319
1320 vlan->mode = MACVLAN_MODE_VEPA; 1320 vlan->mode = MACVLAN_MODE_VEPA;
1321 if (data && data[IFLA_MACVLAN_MODE]) 1321 if (data && data[IFLA_MACVLAN_MODE])
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 076df5360ba5..3a788bf0affd 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3891,8 +3891,7 @@ void netdev_default_l2upper_neigh_destroy(struct net_device *dev,
3891extern u8 netdev_rss_key[NETDEV_RSS_KEY_LEN] __read_mostly; 3891extern u8 netdev_rss_key[NETDEV_RSS_KEY_LEN] __read_mostly;
3892void netdev_rss_key_fill(void *buffer, size_t len); 3892void netdev_rss_key_fill(void *buffer, size_t len);
3893 3893
3894int dev_get_nest_level(struct net_device *dev, 3894int dev_get_nest_level(struct net_device *dev);
3895 bool (*type_check)(const struct net_device *dev));
3896int skb_checksum_help(struct sk_buff *skb); 3895int skb_checksum_help(struct sk_buff *skb);
3897struct sk_buff *__skb_gso_segment(struct sk_buff *skb, 3896struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
3898 netdev_features_t features, bool tx_path); 3897 netdev_features_t features, bool tx_path);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 82a116ba590e..8de138d3306b 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -169,7 +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 vlan->nest_level = dev_get_nest_level(real_dev) + 1;
173 err = register_netdevice(dev); 173 err = register_netdevice(dev);
174 if (err < 0) 174 if (err < 0)
175 goto out_uninit_mvrp; 175 goto out_uninit_mvrp;
diff --git a/net/core/dev.c b/net/core/dev.c
index 4ce07dc25573..dd6ce598de89 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6045,8 +6045,7 @@ void *netdev_lower_dev_get_private(struct net_device *dev,
6045EXPORT_SYMBOL(netdev_lower_dev_get_private); 6045EXPORT_SYMBOL(netdev_lower_dev_get_private);
6046 6046
6047 6047
6048int dev_get_nest_level(struct net_device *dev, 6048int dev_get_nest_level(struct net_device *dev)
6049 bool (*type_check)(const struct net_device *dev))
6050{ 6049{
6051 struct net_device *lower = NULL; 6050 struct net_device *lower = NULL;
6052 struct list_head *iter; 6051 struct list_head *iter;
@@ -6056,15 +6055,12 @@ int dev_get_nest_level(struct net_device *dev,
6056 ASSERT_RTNL(); 6055 ASSERT_RTNL();
6057 6056
6058 netdev_for_each_lower_dev(dev, lower, iter) { 6057 netdev_for_each_lower_dev(dev, lower, iter) {
6059 nest = dev_get_nest_level(lower, type_check); 6058 nest = dev_get_nest_level(lower);
6060 if (max_nest < nest) 6059 if (max_nest < nest)
6061 max_nest = nest; 6060 max_nest = nest;
6062 } 6061 }
6063 6062
6064 if (type_check(dev)) 6063 return max_nest + 1;
6065 max_nest++;
6066
6067 return max_nest;
6068} 6064}
6069EXPORT_SYMBOL(dev_get_nest_level); 6065EXPORT_SYMBOL(dev_get_nest_level);
6070 6066