mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
bonding: Convert balance-rr transmit to new locking
Change locking in balance-rr transmit processing to use a free running counter to determine which slave to transmit on. Instead, a free-running counter is maintained, and modulo arithmetic used to select a slave for transmit. This removes lock operations from the TX path, and eliminates a deadlock introduced by the conversion to work queues. Signed-off-by: Andy Gospodarek <andy@greyhouse.net> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
1b76b31693
commit
cf5f904493
2 changed files with 13 additions and 13 deletions
|
@ -4057,8 +4057,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
|
|||
{
|
||||
struct bonding *bond = bond_dev->priv;
|
||||
struct slave *slave, *start_at;
|
||||
int i;
|
||||
int res = 1;
|
||||
int i, slave_no, res = 1;
|
||||
|
||||
read_lock(&bond->lock);
|
||||
|
||||
|
@ -4066,29 +4065,29 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
|
|||
goto out;
|
||||
}
|
||||
|
||||
read_lock(&bond->curr_slave_lock);
|
||||
slave = start_at = bond->curr_active_slave;
|
||||
read_unlock(&bond->curr_slave_lock);
|
||||
/*
|
||||
* Concurrent TX may collide on rr_tx_counter; we accept that
|
||||
* as being rare enough not to justify using an atomic op here
|
||||
*/
|
||||
slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
|
||||
|
||||
if (!slave) {
|
||||
goto out;
|
||||
bond_for_each_slave(bond, slave, i) {
|
||||
slave_no--;
|
||||
if (slave_no < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start_at = slave;
|
||||
bond_for_each_slave_from(bond, slave, i, start_at) {
|
||||
if (IS_UP(slave->dev) &&
|
||||
(slave->link == BOND_LINK_UP) &&
|
||||
(slave->state == BOND_STATE_ACTIVE)) {
|
||||
res = bond_dev_queue_xmit(bond, skb, slave->dev);
|
||||
|
||||
write_lock(&bond->curr_slave_lock);
|
||||
bond->curr_active_slave = slave->next;
|
||||
write_unlock(&bond->curr_slave_lock);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
out:
|
||||
if (res) {
|
||||
/* no suitable interface, frame not sent */
|
||||
|
|
|
@ -197,6 +197,7 @@ struct bonding {
|
|||
int (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int);
|
||||
__be32 master_ip;
|
||||
u16 flags;
|
||||
u16 rr_tx_counter;
|
||||
struct ad_bond_info ad_info;
|
||||
struct alb_bond_info alb_info;
|
||||
struct bond_params params;
|
||||
|
|
Loading…
Reference in a new issue