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>

authored by Jay Vosburgh and committed by Jeff Garzik cf5f9044 1b76b316

+13 -13
+12 -13
drivers/net/bonding/bond_main.c
··· 4057 4057 { 4058 4058 struct bonding *bond = bond_dev->priv; 4059 4059 struct slave *slave, *start_at; 4060 - int i; 4061 - int res = 1; 4060 + int i, slave_no, res = 1; 4062 4061 4063 4062 read_lock(&bond->lock); 4064 4063 ··· 4065 4066 goto out; 4066 4067 } 4067 4068 4068 - read_lock(&bond->curr_slave_lock); 4069 - slave = start_at = bond->curr_active_slave; 4070 - read_unlock(&bond->curr_slave_lock); 4069 + /* 4070 + * Concurrent TX may collide on rr_tx_counter; we accept that 4071 + * as being rare enough not to justify using an atomic op here 4072 + */ 4073 + slave_no = bond->rr_tx_counter++ % bond->slave_cnt; 4071 4074 4072 - if (!slave) { 4073 - goto out; 4075 + bond_for_each_slave(bond, slave, i) { 4076 + slave_no--; 4077 + if (slave_no < 0) { 4078 + break; 4079 + } 4074 4080 } 4075 4081 4082 + start_at = slave; 4076 4083 bond_for_each_slave_from(bond, slave, i, start_at) { 4077 4084 if (IS_UP(slave->dev) && 4078 4085 (slave->link == BOND_LINK_UP) && 4079 4086 (slave->state == BOND_STATE_ACTIVE)) { 4080 4087 res = bond_dev_queue_xmit(bond, skb, slave->dev); 4081 - 4082 - write_lock(&bond->curr_slave_lock); 4083 - bond->curr_active_slave = slave->next; 4084 - write_unlock(&bond->curr_slave_lock); 4085 - 4086 4088 break; 4087 4089 } 4088 4090 } 4089 - 4090 4091 4091 4092 out: 4092 4093 if (res) {
+1
drivers/net/bonding/bonding.h
··· 197 197 int (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int); 198 198 __be32 master_ip; 199 199 u16 flags; 200 + u16 rr_tx_counter; 200 201 struct ad_bond_info ad_info; 201 202 struct alb_bond_info alb_info; 202 203 struct bond_params params;