--- x/drivers/net/bonding/bond_main.c +++ y/drivers/net/bonding/bond_main.c @@ -2968,7 +2968,6 @@ static void bond_mii_monitor(struct work { struct bonding *bond = container_of(work, struct bonding, mii_work.work); - bool should_notify_peers = false; bool commit; unsigned long delay; struct slave *slave; @@ -2978,46 +2977,29 @@ static void bond_mii_monitor(struct work if (!bond_has_slaves(bond)) goto re_arm; + /* Race avoidance with bond_close cancel of workqueue */ + if (!rtnl_trylock()) { + delay = 1; + goto re_arm; + } rcu_read_lock(); - should_notify_peers = bond_should_notify_peers(bond); commit = !!bond_miimon_inspect(bond); - if (bond->send_peer_notif) { - rcu_read_unlock(); - if (rtnl_trylock()) { - bond->send_peer_notif--; - rtnl_unlock(); - } - } else { - rcu_read_unlock(); - } + if (bond->send_peer_notif) + bond->send_peer_notif--; + rcu_read_unlock(); if (commit) { - /* Race avoidance with bond_close cancel of workqueue */ - if (!rtnl_trylock()) { - delay = 1; - should_notify_peers = false; - goto re_arm; - } - bond_for_each_slave(bond, slave, iter) { bond_commit_link_state(slave, BOND_SLAVE_NOTIFY_LATER); } bond_miimon_commit(bond); - - rtnl_unlock(); /* might sleep, hold no other locks */ } + rtnl_unlock(); re_arm: if (bond->params.miimon) queue_delayed_work(bond->wq, &bond->mii_work, delay); - - if (should_notify_peers) { - if (!rtnl_trylock()) - return; - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); - rtnl_unlock(); - } } static int bond_upper_dev_walk(struct net_device *upper,