Message ID | 20210320223448.2452869-4-olteanv@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Better support for sandwiched LAGs with bridge and DSA | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | success | CCed 7 of 7 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | fail | Errors and warnings before: 0 this patch: 1 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 163 lines checked |
netdev/build_allmodconfig_warn | fail | Errors and warnings before: 0 this patch: 1 |
netdev/header_inline | success | Link |
Hi Vladimir, I love your patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/Vladimir-Oltean/Better-support-for-sandwiched-LAGs-with-bridge-and-DSA/20210321-063842 base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git d773b7957e4fd7b732a163df0e59d31ad4237302 config: arm-mvebu_v5_defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/3aac17167e3de0aeaf5287f9d586725bdc7495a5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Vladimir-Oltean/Better-support-for-sandwiched-LAGs-with-bridge-and-DSA/20210321-063842 git checkout 3aac17167e3de0aeaf5287f9d586725bdc7495a5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from include/linux/device.h:15, from include/linux/dma-mapping.h:7, from include/linux/skbuff.h:31, from include/net/net_namespace.h:39, from include/linux/netdevice.h:37, from include/linux/if_bridge.h:12, from net/dsa/port.c:9: net/dsa/port.c: In function 'dsa_port_clear_brport_flags': >> net/dsa/port.c:166:5: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat=] 166 | "failed to clear bridge port flag %d: %d (%pe)\n", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt' 19 | #define dev_fmt(fmt) fmt | ^~~ net/dsa/port.c:165:4: note: in expansion of macro 'dev_err' 165 | dev_err(dp->ds->dev, | ^~~~~~~ net/dsa/port.c:166:40: note: format string is defined here 166 | "failed to clear bridge port flag %d: %d (%pe)\n", | ~^ | | | int | %ld vim +166 net/dsa/port.c 148 149 static void dsa_port_clear_brport_flags(struct dsa_port *dp, 150 struct netlink_ext_ack *extack) 151 { 152 const unsigned long val = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; 153 const unsigned long mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | 154 BR_BCAST_FLOOD; 155 int flag, err; 156 157 for_each_set_bit(flag, &mask, 32) { 158 struct switchdev_brport_flags flags = {0}; 159 160 flags.mask = BIT(flag); 161 flags.val = val & BIT(flag); 162 163 err = dsa_port_bridge_flags(dp, flags, extack); 164 if (err && err != -EOPNOTSUPP) 165 dev_err(dp->ds->dev, > 166 "failed to clear bridge port flag %d: %d (%pe)\n", 167 flags.val, err, ERR_PTR(err)); 168 } 169 } 170 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Vladimir, I love your patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/Vladimir-Oltean/Better-support-for-sandwiched-LAGs-with-bridge-and-DSA/20210321-063842 base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git d773b7957e4fd7b732a163df0e59d31ad4237302 config: arm64-randconfig-r021-20210321 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 14696baaf4c43fe53f738bc292bbe169eed93d5d) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/3aac17167e3de0aeaf5287f9d586725bdc7495a5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Vladimir-Oltean/Better-support-for-sandwiched-LAGs-with-bridge-and-DSA/20210321-063842 git checkout 3aac17167e3de0aeaf5287f9d586725bdc7495a5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> net/dsa/port.c:167:5: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat] flags.val, err, ERR_PTR(err)); ^~~~~~~~~ include/linux/dev_printk.h:112:32: note: expanded from macro 'dev_err' _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) ~~~ ^~~~~~~~~~~ 1 warning generated. vim +167 net/dsa/port.c 148 149 static void dsa_port_clear_brport_flags(struct dsa_port *dp, 150 struct netlink_ext_ack *extack) 151 { 152 const unsigned long val = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; 153 const unsigned long mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | 154 BR_BCAST_FLOOD; 155 int flag, err; 156 157 for_each_set_bit(flag, &mask, 32) { 158 struct switchdev_brport_flags flags = {0}; 159 160 flags.mask = BIT(flag); 161 flags.val = val & BIT(flag); 162 163 err = dsa_port_bridge_flags(dp, flags, extack); 164 if (err && err != -EOPNOTSUPP) 165 dev_err(dp->ds->dev, 166 "failed to clear bridge port flag %d: %d (%pe)\n", > 167 flags.val, err, ERR_PTR(err)); 168 } 169 } 170 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/net/dsa/port.c b/net/dsa/port.c index fcbe5b1545b8..8dbc6e0db30c 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -122,26 +122,82 @@ void dsa_port_disable(struct dsa_port *dp) rtnl_unlock(); } -static void dsa_port_change_brport_flags(struct dsa_port *dp, - bool bridge_offload) +static int dsa_port_inherit_brport_flags(struct dsa_port *dp, + struct netlink_ext_ack *extack) { - struct switchdev_brport_flags flags; - int flag; + const unsigned long mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | + BR_BCAST_FLOOD; + struct net_device *brport_dev = dsa_port_to_bridge_port(dp); + int flag, err; - flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; - if (bridge_offload) - flags.val = flags.mask; - else - flags.val = flags.mask & ~BR_LEARNING; + for_each_set_bit(flag, &mask, 32) { + struct switchdev_brport_flags flags = {0}; - for_each_set_bit(flag, &flags.mask, 32) { - struct switchdev_brport_flags tmp; + flags.mask = BIT(flag); - tmp.val = flags.val & BIT(flag); - tmp.mask = BIT(flag); + if (br_port_flag_is_set(brport_dev, BIT(flag))) + flags.val = BIT(flag); - dsa_port_bridge_flags(dp, tmp, NULL); + err = dsa_port_bridge_flags(dp, flags, extack); + if (err && err != -EOPNOTSUPP) + return err; } + + return 0; +} + +static void dsa_port_clear_brport_flags(struct dsa_port *dp, + struct netlink_ext_ack *extack) +{ + const unsigned long val = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; + const unsigned long mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | + BR_BCAST_FLOOD; + int flag, err; + + for_each_set_bit(flag, &mask, 32) { + struct switchdev_brport_flags flags = {0}; + + flags.mask = BIT(flag); + flags.val = val & BIT(flag); + + err = dsa_port_bridge_flags(dp, flags, extack); + if (err && err != -EOPNOTSUPP) + dev_err(dp->ds->dev, + "failed to clear bridge port flag %d: %d (%pe)\n", + flags.val, err, ERR_PTR(err)); + } +} + +static int dsa_port_switchdev_sync(struct dsa_port *dp, + struct netlink_ext_ack *extack) +{ + int err; + + err = dsa_port_inherit_brport_flags(dp, extack); + if (err) + return err; + + return 0; +} + +/* Configure the port for standalone mode (no address learning, flood + * everything, BR_STATE_FORWARDING, etc). + * The bridge only emits SWITCHDEV_ATTR_ID_PORT_* events when the user + * requests it through netlink or sysfs, but not automatically at port + * join or leave, so we need to handle resetting the brport flags ourselves. + * But we even prefer it that way, because otherwise, some setups might never + * get the notification they need, for example, when a port leaves a LAG that + * offloads the bridge, it becomes standalone, but as far as the bridge is + * concerned, no port ever left. + */ +static void dsa_port_switchdev_unsync(struct dsa_port *dp) +{ + dsa_port_clear_brport_flags(dp, NULL); + + /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, + * so allow it to be in BR_STATE_FORWARDING to be kept functional + */ + dsa_port_set_state_now(dp, BR_STATE_FORWARDING); } int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, @@ -155,24 +211,25 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, }; int err; - /* Notify the port driver to set its configurable flags in a way that - * matches the initial settings of a bridge port. - */ - dsa_port_change_brport_flags(dp, true); - /* Here the interface is already bridged. Reflect the current * configuration so that drivers can program their chips accordingly. */ dp->bridge_dev = br; err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_JOIN, &info); + if (err) + goto out_rollback; - /* The bridging is rolled back on error */ - if (err) { - dsa_port_change_brport_flags(dp, false); - dp->bridge_dev = NULL; - } + err = dsa_port_switchdev_sync(dp, extack); + if (err) + goto out_rollback_unbridge; + return 0; + +out_rollback_unbridge: + dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); +out_rollback: + dp->bridge_dev = NULL; return err; } @@ -186,6 +243,8 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) }; int err; + dsa_port_switchdev_unsync(dp); + /* Here the port is already unbridged. Reflect the current configuration * so that drivers can program their chips accordingly. */ @@ -194,24 +253,6 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); if (err) pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); - - /* Configure the port for standalone mode (no address learning, - * flood everything). - * The bridge only emits SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS events - * when the user requests it through netlink or sysfs, but not - * automatically at port join or leave, so we need to handle resetting - * the brport flags ourselves. But we even prefer it that way, because - * otherwise, some setups might never get the notification they need, - * for example, when a port leaves a LAG that offloads the bridge, - * it becomes standalone, but as far as the bridge is concerned, no - * port ever left. - */ - dsa_port_change_brport_flags(dp, false); - - /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, - * so allow it to be in BR_STATE_FORWARDING to be kept functional - */ - dsa_port_set_state_now(dp, BR_STATE_FORWARDING); } int dsa_port_lag_change(struct dsa_port *dp,