Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf5f9044 authored by Jay Vosburgh's avatar Jay Vosburgh Committed by Jeff Garzik
Browse files

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: default avatarAndy Gospodarek <andy@greyhouse.net>
Signed-off-by: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 1b76b316
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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;