bonding: Add helper function to get the xmit slave in rr mode
authorMaor Gottlieb <maorg@mellanox.com>
Thu, 30 Apr 2020 19:21:36 +0000 (22:21 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 1 May 2020 19:15:37 +0000 (12:15 -0700)
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>
drivers/net/bonding/bond_main.c

index 8e63059..09c8485 100644 (file)
@@ -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;
 }