summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorHangbin Liu <liuhangbin@gmail.com>2026-03-04 15:13:53 +0800
committerJakub Kicinski <kuba@kernel.org>2026-03-06 16:25:16 -0800
commit45fc134bcfadde456639c1b1e206e6918d69a553 (patch)
tree54a761cda8a89fdf89470f8dbca8a4bd0bdd88fe /drivers/net
parent224a0d284c3caf1951302d1744a714784febed71 (diff)
bonding: do not set usable_slaves for broadcast mode
After commit e0caeb24f538 ("net: bonding: update the slave array for broadcast mode"), broadcast mode will also set all_slaves and usable_slaves during bond_enslave(). But if we also set updelay, during enslave, the slave init state will be BOND_LINK_BACK. And later bond_update_slave_arr() will alloc usable_slaves but add nothing. This will cause bond_miimon_inspect() to have ignore_updelay always true. So the updelay will be always ignored. e.g. [ 6.498368] bond0: (slave veth2): link status definitely down, disabling slave [ 7.536371] bond0: (slave veth2): link status up, enabling it in 0 ms [ 7.536402] bond0: (slave veth2): link status definitely up, 10000 Mbps full duplex To fix it, we can either always call bond_update_slave_arr() on every place when link changes. Or, let's just not set usable_slaves for broadcast mode. Fixes: e0caeb24f538 ("net: bonding: update the slave array for broadcast mode") Reported-by: Liang Li <liali@redhat.com> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> Link: https://patch.msgid.link/20260304-b4-bond_updelay-v1-1-f72eb2e454d0@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_main.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 14ed91391fcc..93a32a368d31 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -5069,13 +5069,18 @@ static void bond_set_slave_arr(struct bonding *bond,
{
struct bond_up_slave *usable, *all;
- usable = rtnl_dereference(bond->usable_slaves);
- rcu_assign_pointer(bond->usable_slaves, usable_slaves);
- kfree_rcu(usable, rcu);
-
all = rtnl_dereference(bond->all_slaves);
rcu_assign_pointer(bond->all_slaves, all_slaves);
kfree_rcu(all, rcu);
+
+ if (BOND_MODE(bond) == BOND_MODE_BROADCAST) {
+ kfree_rcu(usable_slaves, rcu);
+ return;
+ }
+
+ usable = rtnl_dereference(bond->usable_slaves);
+ rcu_assign_pointer(bond->usable_slaves, usable_slaves);
+ kfree_rcu(usable, rcu);
}
static void bond_reset_slave_arr(struct bonding *bond)