Place all the arp monitor in a common critical section, to avoid requesting rtnl lock frequently. Note that mii monitor also use the common critical section. It should be noted that the bond_ab_arp_probe() sending probe arp may be lost in this cycle, when committing link changed state. It is acceptable. Cc: Jay Vosburgh Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Simon Horman Cc: Jonathan Corbet Cc: Andrew Lunn Cc: Nikolay Aleksandrov Cc: Hangbin Liu Cc: Jason Xing Signed-off-by: Tonghao Zhang --- drivers/net/bonding/bond_main.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 14396e39b1f0..2cfaac3edde0 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3757,7 +3757,7 @@ static bool bond_ab_arp_probe(struct bonding *bond) static void bond_activebackup_arp_mon(struct bonding *bond) { - bool should_notify_rtnl; + bool should_notify_rtnl, commit; int delta_in_ticks; delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); @@ -3767,36 +3767,28 @@ static void bond_activebackup_arp_mon(struct bonding *bond) rcu_read_lock(); - if (bond_ab_arp_inspect(bond)) { - rcu_read_unlock(); - - /* Race avoidance with bond_close flush of workqueue */ - if (!rtnl_trylock()) { - delta_in_ticks = 1; - goto re_arm; - } - - bond_ab_arp_commit(bond); - - rtnl_unlock(); - rcu_read_lock(); - } - + commit = !!bond_ab_arp_inspect(bond); should_notify_rtnl = bond_ab_arp_probe(bond); + rcu_read_unlock(); - if (READ_ONCE(bond->send_peer_notif) || should_notify_rtnl) { + if (commit || READ_ONCE(bond->send_peer_notif) || should_notify_rtnl) { + /* Race avoidance with bond_close flush of workqueue */ if (!rtnl_trylock()) { delta_in_ticks = 1; goto re_arm; } + if (commit) + bond_ab_arp_commit(bond); + if (bond->send_peer_notif) { if (bond_should_notify_peers(bond)) call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); bond->send_peer_notif--; } + if (should_notify_rtnl) { bond_slave_state_notify(bond); bond_slave_link_notify(bond); -- 2.34.1