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:
Jay Vosburgh 2007-10-17 17:37:47 -07:00 committed by Jeff Garzik
parent 1b76b31693
commit cf5f904493
2 changed files with 13 additions and 13 deletions

View File

@ -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 */

View File

@ -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;