Blob Blame History Raw
From: Maor Gottlieb <maorg@mellanox.com>
Date: Thu, 30 Apr 2020 22:21:36 +0300
Subject: bonding: Add helper function to get the xmit slave in rr mode
Patch-mainline: v5.8-rc1
Git-commit: 29d5bbccb3a171eb146c94efeb3d752fad3ddf7d
References: bsc#1176447

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: Maor Gottlieb <maorg@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Jay Vosburgh <jay.vosburgh@canonical.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/net/bonding/bond_main.c |   43 +++++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 16 deletions(-)

--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -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 netdev_tx_t 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;
@@ -3942,7 +3941,7 @@ static netdev_tx_t bond_xmit_slave_id(st
 	bond_for_each_slave_rcu(bond, slave, iter) {
 		if (--i < 0) {
 			if (bond_slave_can_tx(slave))
-				return bond_dev_queue_xmit(bond, skb, slave->dev);
+				return slave;
 		}
 	}
 
@@ -3952,10 +3951,10 @@ static netdev_tx_t bond_xmit_slave_id(st
 		if (--i < 0)
 			break;
 		if (bond_slave_can_tx(slave))
-			return bond_dev_queue_xmit(bond, skb, slave->dev);
+			return slave;
 	}
 	/* no slave that can tx has been found */
-	return bond_tx_drop(bond->dev, skb);
+	return NULL;
 }
 
 /**
@@ -3991,10 +3990,9 @@ static u32 bond_rr_gen_slave_id(struct b
 	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;
@@ -4016,17 +4014,30 @@ static netdev_tx_t bond_xmit_roundrobin(
 		if (iph->protocol == IPPROTO_IGMP) {
 			slave = rcu_dereference(bond->curr_active_slave);
 			if (slave)
-				return bond_dev_queue_xmit(bond, skb, slave->dev);
-			return bond_xmit_slave_id(bond, skb, 0);
+				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);
-		return bond_xmit_slave_id(bond, skb, slave_id % slave_cnt);
+		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 (likely(slave))
+		return bond_dev_queue_xmit(bond, skb, slave->dev);
+
 	return bond_tx_drop(bond_dev, skb);
 }
 
@@ -4206,7 +4217,7 @@ static netdev_tx_t bond_3ad_xor_xmit(str
 	slaves = rcu_dereference(bond->usable_slaves);
 	slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves);
 	if (likely(slave))
-		bond_dev_queue_xmit(bond, skb, slave->dev);
+		return bond_dev_queue_xmit(bond, skb, slave->dev);
 
 	return bond_tx_drop(dev, skb);
 }