The branch main has been updated by hselasky:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=cf88b86e4954215eb447729042dab8dea722c044

commit cf88b86e4954215eb447729042dab8dea722c044
Author:     Hans Petter Selasky <[email protected]>
AuthorDate: 2021-06-16 13:01:33 +0000
Commit:     Hans Petter Selasky <[email protected]>
CommitDate: 2021-07-12 12:22:30 +0000

    mlx5ib: Fix XRC QP support after introducing extended atomic.
    
    Extended atomics are supported with RC and XRC QP types, but Linux commit
    a60109dc9a95 added an unneeded check to to_mlx5_access_flags().
    This broke XRC QPs.
    
    The following ib_atomic_bw invocation over XRC reproduces the issue:
    ib_atomic_bw -d mlx5_1 --connection=XRC --atomic_type=FETCH_AND_ADD
    
    It is safe to remove such checks because the QP type was already checked
    in ib_modify_qp_is_ok(), which was previously called from
    mlx5_ib_modify_qp().
    
    Linux commit:
    13f8d9c16693afb908ead3d2a758adbe6a79eccd
    
    MFC after:      1 week
    Reviewed by:    kib
    Sponsored by:   Mellanox Technologies // NVIDIA Networking
---
 sys/dev/mlx5/mlx5_ib/mlx5_ib.h    |  2 +
 sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c | 85 ++++++++++++++++++++++++++++++++++-----
 2 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib.h b/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
index fcb1e584fcca..44a9aa307be7 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib.h
@@ -207,6 +207,8 @@ struct mlx5_ib_flow_db {
  * creates the actual hardware QP.
  */
 #define MLX5_IB_QPT_HW_GSI     IB_QPT_RESERVED2
+#define MLX5_IB_QPT_DCI                IB_QPT_RESERVED3
+#define MLX5_IB_QPT_DCT                IB_QPT_RESERVED4
 #define MLX5_IB_WR_UMR         IB_WR_RESERVED1
 
 /* Private QP creation flags to be passed in ib_qp_init_attr.create_flags.
diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c 
b/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c
index bc17ee56c7d0..8f05b32a3261 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_qp.c
@@ -1504,6 +1504,53 @@ err:
        return err;
 }
 
+static int atomic_size_to_mode(int size_mask)
+{
+       /* driver does not support atomic_size > 256B
+        * and does not know how to translate bigger sizes
+        */
+       int supported_size_mask = size_mask & 0x1ff;
+       int log_max_size;
+
+       if (!supported_size_mask)
+               return -EOPNOTSUPP;
+
+       log_max_size = __fls(supported_size_mask);
+
+       if (log_max_size > 3)
+               return log_max_size;
+
+       return MLX5_ATOMIC_MODE_8B;
+}
+
+static int get_atomic_mode(struct mlx5_ib_dev *dev,
+                          enum ib_qp_type qp_type)
+{
+       u8 atomic_operations = MLX5_CAP_ATOMIC(dev->mdev, atomic_operations);
+       u8 atomic = MLX5_CAP_GEN(dev->mdev, atomic);
+       int atomic_mode = -EOPNOTSUPP;
+       int atomic_size_mask;
+
+       if (!atomic)
+               return -EOPNOTSUPP;
+
+       if (qp_type == MLX5_IB_QPT_DCT)
+               atomic_size_mask = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_dc);
+       else
+               atomic_size_mask = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_qp);
+
+       if ((atomic_operations & MLX5_ATOMIC_OPS_MASKED_CMP_SWAP) ||
+           (atomic_operations & MLX5_ATOMIC_OPS_MASKED_FETCH_ADD))
+               atomic_mode = atomic_size_to_mode(atomic_size_mask);
+
+       if (atomic_mode <= 0 &&
+           (atomic_operations & MLX5_ATOMIC_OPS_CMP_SWAP &&
+            atomic_operations & MLX5_ATOMIC_OPS_FETCH_ADD))
+               atomic_mode = MLX5_ATOMIC_MODE_IB_COMP;
+
+       return atomic_mode;
+}
+
 static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                            struct ib_qp_init_attr *init_attr,
                            struct ib_udata *udata, struct mlx5_ib_qp *qp)
@@ -2119,12 +2166,14 @@ int mlx5_ib_destroy_qp(struct ib_qp *qp)
        return 0;
 }
 
-static __be32 to_mlx5_access_flags(struct mlx5_ib_qp *qp, const struct 
ib_qp_attr *attr,
-                                  int attr_mask)
+static int to_mlx5_access_flags(struct mlx5_ib_qp *qp,
+                               const struct ib_qp_attr *attr,
+                               int attr_mask, __be32 *hw_access_flags_be)
 {
-       u32 hw_access_flags = 0;
        u8 dest_rd_atomic;
-       u32 access_flags;
+       u32 access_flags, hw_access_flags = 0;
+
+       struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device);
 
        if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
                dest_rd_atomic = attr->max_dest_rd_atomic;
@@ -2141,12 +2190,23 @@ static __be32 to_mlx5_access_flags(struct mlx5_ib_qp 
*qp, const struct ib_qp_att
 
        if (access_flags & IB_ACCESS_REMOTE_READ)
                hw_access_flags |= MLX5_QP_BIT_RRE;
-       if (access_flags & IB_ACCESS_REMOTE_ATOMIC)
-               hw_access_flags |= (MLX5_QP_BIT_RAE | MLX5_ATOMIC_MODE_CX);
+       if (access_flags & IB_ACCESS_REMOTE_ATOMIC) {
+               int atomic_mode;
+
+               atomic_mode = get_atomic_mode(dev, qp->ibqp.qp_type);
+               if (atomic_mode < 0)
+                       return -EOPNOTSUPP;
+
+               hw_access_flags |= MLX5_QP_BIT_RAE;
+               hw_access_flags |= atomic_mode << MLX5_ATOMIC_MODE_OFF;
+       }
+
        if (access_flags & IB_ACCESS_REMOTE_WRITE)
                hw_access_flags |= MLX5_QP_BIT_RWE;
 
-       return cpu_to_be32(hw_access_flags);
+       *hw_access_flags_be = cpu_to_be32(hw_access_flags);
+
+       return 0;
 }
 
 enum {
@@ -2730,8 +2790,15 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                                cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) 
<< 21);
        }
 
-       if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC))
-               context->params2 |= to_mlx5_access_flags(qp, attr, attr_mask);
+       if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {
+               __be32 access_flags;
+
+               err = to_mlx5_access_flags(qp, attr, attr_mask, &access_flags);
+               if (err)
+                       goto out;
+
+               context->params2 |= access_flags;
+       }
 
        if (attr_mask & IB_QP_MIN_RNR_TIMER)
                context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 
24);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "[email protected]"

Reply via email to