diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 47 | 
1 files changed, 23 insertions, 24 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4da619210c1f..e95e593cd12d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2287,7 +2287,9 @@ skip_mac_set:  		unblock_netpoll_tx();  	} -	if (bond_mode_can_use_xmit_hash(bond)) +	/* broadcast mode uses the all_slaves to loop through slaves. */ +	if (bond_mode_can_use_xmit_hash(bond) || +	    BOND_MODE(bond) == BOND_MODE_BROADCAST)  		bond_update_slave_arr(bond, NULL);  	if (!slave_dev->netdev_ops->ndo_bpf || @@ -2463,7 +2465,8 @@ static int __bond_release_one(struct net_device *bond_dev,  	bond_upper_dev_unlink(bond, slave); -	if (bond_mode_can_use_xmit_hash(bond)) +	if (bond_mode_can_use_xmit_hash(bond) || +	    BOND_MODE(bond) == BOND_MODE_BROADCAST)  		bond_update_slave_arr(bond, slave);  	slave_info(bond_dev, slave_dev, "Releasing %s interface\n", @@ -2871,7 +2874,7 @@ static void bond_mii_monitor(struct work_struct *work)  {  	struct bonding *bond = container_of(work, struct bonding,  					    mii_work.work); -	bool should_notify_peers = false; +	bool should_notify_peers;  	bool commit;  	unsigned long delay;  	struct slave *slave; @@ -2883,30 +2886,33 @@ static void bond_mii_monitor(struct work_struct *work)  		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 (commit) { +	rcu_read_unlock(); + +	if (commit || bond->send_peer_notif) {  		/* 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); +		if (commit) { +			bond_for_each_slave(bond, slave, iter) { +				bond_commit_link_state(slave, +						       BOND_SLAVE_NOTIFY_LATER); +			} +			bond_miimon_commit(bond); +		} + +		if (bond->send_peer_notif) { +			bond->send_peer_notif--; +			if (should_notify_peers) +				call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, +							 bond->dev);  		} -		bond_miimon_commit(bond);  		rtnl_unlock();	/* might sleep, hold no other locks */  	} @@ -2914,13 +2920,6 @@ static void bond_mii_monitor(struct work_struct *work)  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,  | 
