This is a note to let you know that I've just added the patch titled net: Find the nesting level of a given device by type. to the 3.14-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: net-find-the-nesting-level-of-a-given-device-by-type.patch and it can be found in the queue-3.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Wed May 28 21:03:54 PDT 2014 From: Vlad Yasevich <vyasevic@xxxxxxxxxx> Date: Fri, 16 May 2014 17:04:53 -0400 Subject: net: Find the nesting level of a given device by type. From: Vlad Yasevich <vyasevic@xxxxxxxxxx> [ Upstream commit 4085ebe8c31face855fd01ee40372cb4aab1df3a ] Multiple devices in the kernel can be stacked/nested and they need to know their nesting level for the purposes of lockdep. This patch provides a generic function that determines a nesting level of a particular device by its type (ex: vlan, macvlan, etc). We only care about nesting of the same type of devices. For example: eth0 <- vlan0.10 <- macvlan0 <- vlan1.20 The nesting level of vlan1.20 would be 1, since there is another vlan in the stack under it. Signed-off-by: Vlad Yasevich <vyasevic@xxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- include/linux/netdevice.h | 10 +++++++++ net/core/dev.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2988,6 +2988,14 @@ void *netdev_lower_get_next_private_rcu( 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); @@ -3003,6 +3011,8 @@ void netdev_upper_dev_unlink(struct net_ 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); --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4605,6 +4605,32 @@ void *netdev_lower_get_next_private_rcu( EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); /** + * netdev_lower_get_next - Get the next device from the lower neighbour + * list + * @dev: device + * @iter: list_head ** of the current position + * + * Gets the next netdev_adjacent from the dev's lower neighbour + * list, starting from iter position. The caller must hold RTNL lock or + * its own locking that guarantees that the neighbour lower + * list will remain unchainged. + */ +void *netdev_lower_get_next(struct net_device *dev, struct list_head **iter) +{ + struct netdev_adjacent *lower; + + lower = list_entry((*iter)->next, struct netdev_adjacent, list); + + if (&lower->list == &dev->adj_list.lower) + return NULL; + + *iter = &lower->list; + + return lower->dev; +} +EXPORT_SYMBOL(netdev_lower_get_next); + +/** * netdev_lower_get_first_private_rcu - Get the first ->private from the * lower neighbour list, RCU * variant @@ -5054,6 +5080,30 @@ void *netdev_lower_dev_get_private(struc } EXPORT_SYMBOL(netdev_lower_dev_get_private); + +int dev_get_nest_level(struct net_device *dev, + bool (*type_check)(struct net_device *dev)) +{ + struct net_device *lower = NULL; + struct list_head *iter; + int max_nest = -1; + int nest; + + ASSERT_RTNL(); + + netdev_for_each_lower_dev(dev, lower, iter) { + nest = dev_get_nest_level(lower, type_check); + if (max_nest < nest) + max_nest = nest; + } + + if (type_check(dev)) + max_nest++; + + return max_nest; +} +EXPORT_SYMBOL(dev_get_nest_level); + static void dev_change_rx_flags(struct net_device *dev, int flags) { const struct net_device_ops *ops = dev->netdev_ops; Patches currently in stable-queue which might be from vyasevic@xxxxxxxxxx are queue-3.14/net-start-with-correct-mac_len-in-skb_network_protocol.patch queue-3.14/net-find-the-nesting-level-of-a-given-device-by-type.patch queue-3.14/mactap-fix-checksum-errors-for-non-gso-packets-in.patch queue-3.14/net-allow-for-more-then-a-single-subclass-for.patch queue-3.14/macvlan-fix-lockdep-warnings-with-stacked-macvlan.patch queue-3.14/revert-macvlan-fix-checksums-error-when-we-are-in.patch queue-3.14/net-sctp-cache-auth_enable-per-endpoint.patch queue-3.14/net-sctp-test-if-association-is-dead-in-sctp_wake_up_waiters.patch queue-3.14/net-sctp-wake-up-all-assocs-if-sndbuf-policy-is-per-socket.patch queue-3.14/vlan-fix-lockdep-warning-with-stacked-vlan-devices.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html