This is an AI-generated review of your patch. The human sending this email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html --- net: use ndo_update_offloads to set offload features for bonding/bridge/team This patch converts bonding, bridge, and team drivers to use the new ndo_update_offloads callback, centralizing offload feature computation during port add/remove operations. > diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c > index 90b71bd53040..ea6bb20f9348 100644 > --- a/drivers/net/bonding/bond_main.c > +++ b/drivers/net/bonding/bond_main.c [ ... ] > diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c > index b7282f5c9632..affbcc6fc130 100644 > --- a/drivers/net/team/team_core.c > +++ b/drivers/net/team/team_core.c > @@ -1247,7 +1247,6 @@ static int team_port_add(struct team *team, struct > net_device *port_dev, > port->index = -1; > list_add_tail_rcu(&port->list, &team->port_list); > team_port_enable(team, port); > - netdev_compute_master_upper_features(team->dev, true); > __team_port_change_port_added(port, !!netif_oper_up(port_dev)); > __team_options_change_check(team); [ ... ] > diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c > index d39571e13744..030248bc94c5 100644 > --- a/net/bridge/br_if.c > +++ b/net/bridge/br_if.c > @@ -680,8 +680,6 @@ int br_add_if(struct net_bridge *br, struct net_device > *dev, > > br_mtu_auto_adjust(br); > > - netdev_compute_master_upper_features(br->dev, false); > - > kobject_uevent(&p->kobj, KOBJ_ADD); > > return 0; [ ... ] > diff --git a/net/core/dev.c b/net/core/dev.c > index bbd532aa6a1b..8bcbf7c22830 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -8923,6 +8923,9 @@ static int __netdev_upper_dev_link(struct net_device > *dev, > __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, > priv); > > + /* re-compute all features after adding link */ > + netdev_change_features(upper_dev); > + > return 0; > > rollback: Could this netdev_change_features() call happen too early for team and bridge drivers? The call triggers __netdev_update_features(), which invokes both ndo_update_offloads() and ndo_fix_features(). While ndo_update_offloads() works with the netdev lower device list (already updated by __netdev_adjacent_dev_link_neighbour()), the ndo_fix_features() callbacks iterate driver-specific port lists. For team_port_add(): drivers/net/team/team_core.c:team_port_add() { ... team_upper_dev_link(team, port, extack); /* line ~1231 */ netdev_upper_dev_link() __netdev_upper_dev_link() netdev_change_features() /* <-- triggers feature update */ __netdev_update_features() ops->ndo_fix_features() /* team_fix_features() */ list_add_tail_rcu(&port->list, &team->port_list); /* line 1247 */ ... } team_fix_features() iterates team->port_list to compute features, but the new port hasn't been added to that list yet. Similarly for br_add_if(): net/bridge/br_if.c:br_add_if() { ... netdev_master_upper_dev_link(dev, br->dev, NULL, NULL, extack); /* line ~628 */ __netdev_upper_dev_link() netdev_change_features() /* <-- triggers feature update */ __netdev_update_features() ops->ndo_fix_features() /* br_fix_features() */ list_add_rcu(&p->list, &br->port_list); /* line 634 */ ... } br_fix_features() calls br_features_recompute() which iterates br->port_list, but the new port isn't in that list yet. If the new port lacks support for a feature the master currently has enabled (like NETIF_F_SG, NETIF_F_IP_CSUM, or NETIF_F_TSO), that feature would remain incorrectly enabled. The old code path called netdev_compute_master_upper_features() AFTER the port was added to the driver list, so the new port's capabilities were included in the feature computation. The bonding driver isn't affected because bond_fix_features() uses bond_for_each_slave(), which maps to netdev_for_each_lower_private() and iterates the netdev infrastructure's lower device list rather than a separate driver list.

