Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
authorSaeed Mahameed <saeedm@mellanox.com>
Sat, 9 May 2020 07:06:35 +0000 (00:06 -0700)
committerSaeed Mahameed <saeedm@mellanox.com>
Sat, 9 May 2020 08:05:30 +0000 (01:05 -0700)
This merge includes updates to bonding driver needed for the rdma stack,
to avoid conflicts with the RDMA branch.

Maor Gottlieb Says:

====================
Bonding: Add support to get xmit slave

The following series adds support to get the LAG master xmit slave by
introducing new .ndo - ndo_get_xmit_slave. Every LAG module can
implement it and it first implemented in the bond driver.
This is follow-up to the RFC discussion [1].

The main motivation for doing this is for drivers that offload part
of the LAG functionality. For example, Mellanox Connect-X hardware
implements RoCE LAG which selects the TX affinity when the resources
are created and port is remapped when it goes down.

The first part of this patchset introduces the new .ndo and add the
support to the bonding module.

The second part adds support to get the RoCE LAG xmit slave by building
skb of the RoCE packet based on the AH attributes and call to the new
.ndo.

The third part change the mlx5 driver driver to set the QP's affinity
port according to the slave which found by the .ndo.
====================

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
1  2 
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
include/linux/netdevice.h
include/net/bonding.h
net/core/dev.c

index 3a598d04b1568fbceb42ffe852d193da179d3d17,e863c694c309de90159848569be59b9d6f9241d1..095ea51d185393ba6900c5724d317de27043cd63
@@@ -1328,14 -1329,16 +1328,14 @@@ static netdev_tx_t bond_do_alb_xmit(str
        }
  
        /* no suitable interface, frame not sent */
 -      bond_tx_drop(bond->dev, skb);
 -out:
 -      return NETDEV_TX_OK;
 +      return bond_tx_drop(bond->dev, skb);
  }
  
- netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
+ struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
+                                     struct sk_buff *skb)
  {
-       struct bonding *bond = netdev_priv(bond_dev);
-       struct ethhdr *eth_data;
        struct slave *tx_slave = NULL;
+       struct ethhdr *eth_data;
        u32 hash_index;
  
        skb_reset_mac_header(skb);
index 4f9e7c421f57d7841f11c03135e721ae759c31a8,39b1ad7edbb4a5bf74315ace6e0567e8c734bbe5..a25c65d4af71649a6b81441ed11903128395b9c7
@@@ -3952,10 -3951,10 +3951,10 @@@ static struct slave *bond_get_slave_by_
                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;
  }
  
  /**
@@@ -4024,12 -4022,32 +4022,31 @@@ static struct slave *bond_xmit_roundrob
  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);
        }
 -      if (slave)
 -              bond_dev_queue_xmit(bond, skb, slave->dev);
 -      else
 -              bond_tx_drop(bond_dev, skb);
 -      return NETDEV_TX_OK;
+       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);
  }
  
+ static struct slave *bond_xmit_activebackup_slave_get(struct bonding *bond,
+                                                     struct sk_buff *skb)
+ {
+       return rcu_dereference(bond->curr_active_slave);
+ }
  /* In active-backup mode, we know that bond->curr_active_slave is always valid if
   * the bond has a usable interface.
   */
@@@ -4039,11 -4057,13 +4056,11 @@@ static netdev_tx_t bond_xmit_activeback
        struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
  
-       slave = rcu_dereference(bond->curr_active_slave);
+       slave = bond_xmit_activebackup_slave_get(bond, skb);
        if (slave)
 -              bond_dev_queue_xmit(bond, skb, slave->dev);
 -      else
 -              bond_tx_drop(bond_dev, skb);
 +              return bond_dev_queue_xmit(bond, skb, slave->dev);
  
 -      return NETDEV_TX_OK;
 +      return bond_tx_drop(bond_dev, skb);
  }
  
  /* Use this to update slave_array when (a) it's not appropriate to update
@@@ -4178,17 -4254,17 +4251,15 @@@ static netdev_tx_t bond_3ad_xor_xmit(st
                                     struct net_device *dev)
  {
        struct bonding *bond = netdev_priv(dev);
-       struct slave *slave;
        struct bond_up_slave *slaves;
-       unsigned int count;
+       struct slave *slave;
  
-       slaves = rcu_dereference(bond->slave_arr);
-       count = slaves ? READ_ONCE(slaves->count) : 0;
-       if (likely(count)) {
-               slave = slaves->arr[bond_xmit_hash(bond, skb) % count];
+       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);
 -      else
 -              bond_tx_drop(dev, skb);
 +              return bond_dev_queue_xmit(bond, skb, slave->dev);
-       }
 -      return NETDEV_TX_OK;
 +      return bond_tx_drop(dev, skb);
  }
  
  /* in broadcast mode, we send everything to all usable interfaces. */
Simple merge
Simple merge
diff --cc net/core/dev.c
Simple merge