|
@@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
|
|
|
struct net_device *bond_dev, *vlan_dev, *upper_dev;
|
|
|
struct vlan_entry *vlan;
|
|
|
|
|
|
- rcu_read_lock();
|
|
|
read_lock(&bond->lock);
|
|
|
+ rcu_read_lock();
|
|
|
|
|
|
bond_dev = bond->dev;
|
|
|
|
|
@@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
|
|
|
if (vlan_dev)
|
|
|
__bond_resend_igmp_join_requests(vlan_dev);
|
|
|
}
|
|
|
+ rcu_read_unlock();
|
|
|
|
|
|
- if (--bond->igmp_retrans > 0)
|
|
|
+ /* We use curr_slave_lock to protect against concurrent access to
|
|
|
+ * igmp_retrans from multiple running instances of this function and
|
|
|
+ * bond_change_active_slave
|
|
|
+ */
|
|
|
+ write_lock_bh(&bond->curr_slave_lock);
|
|
|
+ if (bond->igmp_retrans > 1) {
|
|
|
+ bond->igmp_retrans--;
|
|
|
queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
|
|
|
-
|
|
|
+ }
|
|
|
+ write_unlock_bh(&bond->curr_slave_lock);
|
|
|
read_unlock(&bond->lock);
|
|
|
- rcu_read_unlock();
|
|
|
}
|
|
|
|
|
|
static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
|