Skip to content

Commit

Permalink
bonding: remove bond read lock for bond_alb_monitor()
Browse files Browse the repository at this point in the history
The bond slave list may change when the monitor is running, the slave list is no longer
protected by bond->lock, only protected by rtnl lock(), so we have 3 ways to modify it:
1.add bond_master_upper_dev_link() and bond_upper_dev_unlink() in bond->lock, but it is unsafe
to call call_netdevice_notifiers() in write lock.
2.remove unused bond->lock for monitor function, only use the existing rtnl lock().
3.use rcu_read_lock() to protect it, of course, it will transform bond_for_each_slave to
bond_for_each_slave_rcu() and performance is better, but in slow path, it is ignored.
so I remove the bond->lock and move the rtnl lock to protect the whole monitor function.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
dingtianhong authored and David S. Miller committed Oct 27, 2013
1 parent 6b6c526 commit 2d0dafb
Showing 1 changed file with 4 additions and 16 deletions.
20 changes: 4 additions & 16 deletions drivers/net/bonding/bond_alb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1495,11 +1495,13 @@ void bond_alb_monitor(struct work_struct *work)
struct list_head *iter;
struct slave *slave;

read_lock(&bond->lock);
if (!rtnl_trylock())
goto re_arm;

if (!bond_has_slaves(bond)) {
bond_info->tx_rebalance_counter = 0;
bond_info->lp_counter = 0;
rtnl_unlock();
goto re_arm;
}

Expand Down Expand Up @@ -1548,16 +1550,6 @@ void bond_alb_monitor(struct work_struct *work)
if (bond_info->primary_is_promisc &&
(++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {

/*
* dev_set_promiscuity requires rtnl and
* nothing else. Avoid race with bond_close.
*/
read_unlock(&bond->lock);
if (!rtnl_trylock()) {
read_lock(&bond->lock);
goto re_arm;
}

bond_info->rlb_promisc_timeout_counter = 0;

/* If the primary was set to promiscuous mode
Expand All @@ -1566,9 +1558,6 @@ void bond_alb_monitor(struct work_struct *work)
*/
dev_set_promiscuity(bond->curr_active_slave->dev, -1);
bond_info->primary_is_promisc = 0;

rtnl_unlock();
read_lock(&bond->lock);
}

if (bond_info->rlb_rebalance) {
Expand All @@ -1591,10 +1580,9 @@ void bond_alb_monitor(struct work_struct *work)
}
}

rtnl_unlock();
re_arm:
queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks);

read_unlock(&bond->lock);
}

/* assumption: called before the slave is attached to the bond
Expand Down

0 comments on commit 2d0dafb

Please sign in to comment.