]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
RDMA/mlx5: Fix affinity assignment
authorMark Bloch <mbloch@nvidia.com>
Mon, 5 Jun 2023 10:33:26 +0000 (13:33 +0300)
committerLeon Romanovsky <leon@kernel.org>
Sun, 11 Jun 2023 08:27:17 +0000 (11:27 +0300)
The cited commit aimed to ensure that Virtual Functions (VFs) assign a
queue affinity to a Queue Pair (QP) to distribute traffic when
the LAG master creates a hardware LAG. If the affinity was set while
the hardware was not in LAG, the firmware would ignore the affinity value.

However, this commit unintentionally assigned an affinity to QPs on the LAG
master's VPORT even if the RDMA device was not marked as LAG-enabled.
In most cases, this was not an issue because when the hardware entered
hardware LAG configuration, the RDMA device of the LAG master would be
destroyed and a new one would be created, marked as LAG-enabled.

The problem arises when a user configures Equal-Cost Multipath (ECMP).
In ECMP mode, traffic can be directed to different physical ports based on
the queue affinity, which is intended for use by VPORTS other than the
E-Switch manager. ECMP mode is supported only if both E-Switch managers are
in switchdev mode and the appropriate route is configured via IP. In this
configuration, the RDMA device is not destroyed, and we retain the RDMA
device that is not marked as LAG-enabled.

To ensure correct behavior, Send Queues (SQs) opened by the E-Switch
manager through verbs should be assigned strict affinity. This means they
will only be able to communicate through the native physical port
associated with the E-Switch manager. This will prevent the firmware from
assigning affinity and will not allow the SQs to be remapped in case of
failover.

Fixes: 802dcc7fc5ec ("RDMA/mlx5: Support TX port affinity for VF drivers in LAG mode")
Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
Link: https://lore.kernel.org/r/425b05f4da840bc684b0f7e8ebf61aeb5cef09b0.1685960567.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/qp.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
include/linux/mlx5/driver.h

index 91fc0cdf377d106a06312dd55e68f4741ecf6201..2dfa6f49a6f4816c7c0bad61d5928a6e38187e5f 100644 (file)
@@ -1598,6 +1598,9 @@ static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev)
            MLX5_CAP_PORT_SELECTION(dev->mdev, port_select_flow_table_bypass))
                return 0;
 
+       if (mlx5_lag_is_lacp_owner(dev->mdev) && !dev->lag_active)
+               return 0;
+
        return dev->lag_active ||
                (MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&
                 MLX5_CAP_GEN(dev->mdev, lag_tx_port_affinity));
index 70ca8ffa9256b1d11a48bbc5d50a6506a5813671..78b96bfb4e6ac9df9bb24f0f5a29a76ed4520b0a 100644 (file)
@@ -1237,6 +1237,9 @@ static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
 
        MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);
        MLX5_SET(tisc, tisc, transport_domain, tdn);
+       if (!mlx5_ib_lag_should_assign_affinity(dev) &&
+           mlx5_lag_is_lacp_owner(dev->mdev))
+               MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);
        if (qp->flags & IB_QP_CREATE_SOURCE_QPN)
                MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
 
index 1d879374acaa4e2ffceabc6acf5bd4c5896ac31c..229520405d4ae9d74abc7e844e2bea82184c6bf0 100644 (file)
@@ -276,18 +276,6 @@ static inline bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev)
        return pci_num_vf(dev->pdev) ? true : false;
 }
 
-static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
-{
-       /* LACP owner conditions:
-        * 1) Function is physical.
-        * 2) LAG is supported by FW.
-        * 3) LAG is managed by driver (currently the only option).
-        */
-       return  MLX5_CAP_GEN(dev, vport_group_manager) &&
-                  (MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
-                   MLX5_CAP_GEN(dev, lag_master);
-}
-
 int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev);
 static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)
 {
index a4c4f737f9c112a7f760b46571291c50dd008727..8ad16b779898b30bb46e54cfc63f71a3bebb4ce7 100644 (file)
@@ -1237,6 +1237,18 @@ static inline u16 mlx5_core_max_vfs(const struct mlx5_core_dev *dev)
        return dev->priv.sriov.max_vfs;
 }
 
+static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
+{
+       /* LACP owner conditions:
+        * 1) Function is physical.
+        * 2) LAG is supported by FW.
+        * 3) LAG is managed by driver (currently the only option).
+        */
+       return  MLX5_CAP_GEN(dev, vport_group_manager) &&
+                  (MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
+                   MLX5_CAP_GEN(dev, lag_master);
+}
+
 static inline int mlx5_get_gid_table_len(u16 param)
 {
        if (param > 4) {