Commit 29d5bbcc authored by Maor Gottlieb's avatar Maor Gottlieb Committed by Saeed Mahameed
Browse files

bonding: Add helper function to get the xmit slave in rr mode



Add helper function to get the xmit slave when bond is in round
robin mode. Change bond_xmit_slave_id to bond_get_slave_by_id, then
the logic for find the next slave for transmit could be used
both by the xmit flow and the .ndo to get the xmit slave.

Signed-off-by: default avatarMaor Gottlieb <maorg@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Reviewed-by: default avatarJay Vosburgh <jay.vosburgh@canonical.com>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent c071d91d
Loading
Loading
Loading
Loading
+30 −26
Original line number Diff line number Diff line
@@ -3923,16 +3923,15 @@ unwind:
}

/**
 * bond_xmit_slave_id - transmit skb through slave with slave_id
 * bond_get_slave_by_id - get xmit slave with slave_id
 * @bond: bonding device that is transmitting
 * @skb: buffer to transmit
 * @slave_id: slave id up to slave_cnt-1 through which to transmit
 *
 * This function tries to transmit through slave with slave_id but in case
 * This function tries to get slave with slave_id but in case
 * it fails, it tries to find the first available slave for transmission.
 * The skb is consumed in all cases, thus the function is void.
 */
static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
static struct slave *bond_get_slave_by_id(struct bonding *bond,
					  int slave_id)
{
	struct list_head *iter;
	struct slave *slave;
@@ -3941,10 +3940,8 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl
	/* Here we start from the slave with slave_id */
	bond_for_each_slave_rcu(bond, slave, iter) {
		if (--i < 0) {
			if (bond_slave_can_tx(slave)) {
				bond_dev_queue_xmit(bond, skb, slave->dev);
				return;
			}
			if (bond_slave_can_tx(slave))
				return slave;
		}
	}

@@ -3953,13 +3950,11 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl
	bond_for_each_slave_rcu(bond, slave, iter) {
		if (--i < 0)
			break;
		if (bond_slave_can_tx(slave)) {
			bond_dev_queue_xmit(bond, skb, slave->dev);
			return;
		}
		if (bond_slave_can_tx(slave))
			return slave;
	}
	/* no slave that can tx has been found */
	bond_tx_drop(bond->dev, skb);

	return NULL;
}

/**
@@ -3995,10 +3990,9 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
	return slave_id;
}

static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb,
					struct net_device *bond_dev)
static struct slave *bond_xmit_roundrobin_slave_get(struct bonding *bond,
						    struct sk_buff *skb)
{
	struct bonding *bond = netdev_priv(bond_dev);
	struct slave *slave;
	int slave_cnt;
	u32 slave_id;
@@ -4020,21 +4014,31 @@ static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb,
		if (iph->protocol == IPPROTO_IGMP) {
			slave = rcu_dereference(bond->curr_active_slave);
			if (slave)
				bond_dev_queue_xmit(bond, skb, slave->dev);
			else
				bond_xmit_slave_id(bond, skb, 0);
			return NETDEV_TX_OK;
				return slave;
			return bond_get_slave_by_id(bond, 0);
		}
	}

non_igmp:
	slave_cnt = READ_ONCE(bond->slave_cnt);
	if (likely(slave_cnt)) {
		slave_id = bond_rr_gen_slave_id(bond);
		bond_xmit_slave_id(bond, skb, slave_id % slave_cnt);
	} else {
		bond_tx_drop(bond_dev, skb);
		slave_id = bond_rr_gen_slave_id(bond) % slave_cnt;
		return bond_get_slave_by_id(bond, slave_id);
	}
	return NULL;
}

static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb,
					struct net_device *bond_dev)
{
	struct bonding *bond = netdev_priv(bond_dev);
	struct slave *slave;

	slave = bond_xmit_roundrobin_slave_get(bond, skb);
	if (slave)
		bond_dev_queue_xmit(bond, skb, slave->dev);
	else
		bond_tx_drop(bond_dev, skb);
	return NETDEV_TX_OK;
}