aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarod Wilson <jarod@redhat.com>2015-11-03 10:15:59 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-03 11:29:57 -0500
commit5ba3f7d61a3a9e6d94462b207d302931b53d8c61 (patch)
tree1b9db4afc4a9f925eb3eb480bb9657e841b9d0d8
parent74f2d19caff885bc656e9acf2a6e727b66ab0ed1 (diff)
net/core: fix for_each_netdev_feature
As pointed out by Nikolay and further explained by Geert, the initial for_each_netdev_feature macro was broken, as feature would get set outside of the block of code it was intended to run in, thus only ever working for the first feature bit in the mask. While less pretty this way, this is tested and confirmed functional with multiple feature bits set in NETIF_F_UPPER_DISABLES. [root@dell-per730-01 ~]# ethtool -K bond0 lro off ... [ 242.761394] bond0: Disabling feature 0x0000000000008000 on lower dev p5p2. [ 243.552178] bnx2x 0000:06:00.1 p5p2: using MSI-X IRQs: sp 74 fp[0] 76 ... fp[7] 83 [ 244.353978] bond0: Disabling feature 0x0000000000008000 on lower dev p5p1. [ 245.147420] bnx2x 0000:06:00.0 p5p1: using MSI-X IRQs: sp 62 fp[0] 64 ... fp[7] 71 [root@dell-per730-01 ~]# ethtool -K bond0 gro off ... [ 251.925645] bond0: Disabling feature 0x0000000000004000 on lower dev p5p2. [ 252.713693] bnx2x 0000:06:00.1 p5p2: using MSI-X IRQs: sp 74 fp[0] 76 ... fp[7] 83 [ 253.499085] bond0: Disabling feature 0x0000000000004000 on lower dev p5p1. [ 254.290922] bnx2x 0000:06:00.0 p5p1: using MSI-X IRQs: sp 62 fp[0] 64 ... fp[7] 71 Fixes: fd867d51f ("net/core: generic support for disabling netdev features down stack") CC: "David S. Miller" <davem@davemloft.net> CC: Eric Dumazet <edumazet@google.com> CC: Jay Vosburgh <j.vosburgh@gmail.com> CC: Veaceslav Falico <vfalico@gmail.com> CC: Andy Gospodarek <gospo@cumulusnetworks.com> CC: Jiri Pirko <jiri@resnulli.us> CC: Nikolay Aleksandrov <razor@blackwall.org> CC: Michal Kubecek <mkubecek@suse.cz> CC: Alexander Duyck <alexander.duyck@gmail.com> CC: Geert Uytterhoeven <geert@linux-m68k.org> CC: netdev@vger.kernel.org Signed-off-by: Jarod Wilson <jarod@redhat.com> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netdev_features.h6
-rw-r--r--net/core/dev.c8
2 files changed, 8 insertions, 6 deletions
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 0f5837a9b1ba..f0d87347df19 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -125,10 +125,8 @@ enum {
125#define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD) 125#define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD)
126#define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL) 126#define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL)
127 127
128#define for_each_netdev_feature(mask_addr, feature) \ 128#define for_each_netdev_feature(mask_addr, bit) \
129 int bit; \ 129 for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT)
130 for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) \
131 feature = __NETIF_F_BIT(bit);
132 130
133/* Features valid for ethtool to change */ 131/* Features valid for ethtool to change */
134/* = all defined minus driver/device-class-related */ 132/* = all defined minus driver/device-class-related */
diff --git a/net/core/dev.c b/net/core/dev.c
index c4d2b430788d..8ce3f74cd6b9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6293,8 +6293,10 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
6293{ 6293{
6294 netdev_features_t upper_disables = NETIF_F_UPPER_DISABLES; 6294 netdev_features_t upper_disables = NETIF_F_UPPER_DISABLES;
6295 netdev_features_t feature; 6295 netdev_features_t feature;
6296 int feature_bit;
6296 6297
6297 for_each_netdev_feature(&upper_disables, feature) { 6298 for_each_netdev_feature(&upper_disables, feature_bit) {
6299 feature = __NETIF_F_BIT(feature_bit);
6298 if (!(upper->wanted_features & feature) 6300 if (!(upper->wanted_features & feature)
6299 && (features & feature)) { 6301 && (features & feature)) {
6300 netdev_dbg(lower, "Dropping feature %pNF, upper dev %s has it off.\n", 6302 netdev_dbg(lower, "Dropping feature %pNF, upper dev %s has it off.\n",
@@ -6311,8 +6313,10 @@ static void netdev_sync_lower_features(struct net_device *upper,
6311{ 6313{
6312 netdev_features_t upper_disables = NETIF_F_UPPER_DISABLES; 6314 netdev_features_t upper_disables = NETIF_F_UPPER_DISABLES;
6313 netdev_features_t feature; 6315 netdev_features_t feature;
6316 int feature_bit;
6314 6317
6315 for_each_netdev_feature(&upper_disables, feature) { 6318 for_each_netdev_feature(&upper_disables, feature_bit) {
6319 feature = __NETIF_F_BIT(feature_bit);
6316 if (!(features & feature) && (lower->features & feature)) { 6320 if (!(features & feature) && (lower->features & feature)) {
6317 netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n", 6321 netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n",
6318 &feature, lower->name); 6322 &feature, lower->name);