Blame SOURCES/0003-mlx5-Allow-creation-of-a-Multi-Packet-RQ-using-direc.patch

95af3a
From de7ba62097bef7a75bb995d2ea48704eccc5e4f8 Mon Sep 17 00:00:00 2001
95af3a
From: Noa Osherovich <noaos@mellanox.com>
95af3a
Date: Sun, 6 Aug 2017 10:28:48 +0300
95af3a
Subject: [PATCH rdma-core 3/3] mlx5: Allow creation of a Multi-Packet RQ using
95af3a
 direct verbs
95af3a
95af3a
Add needed definitions to allow creation of a Multi-Packet RQ using the
95af3a
mlx5 direct verbs interface.
95af3a
95af3a
In order to create a Multi-Packet RQ, one needs to provide a
95af3a
mlx5dv_wq_init_attr containing the following information in its
95af3a
striding_rq_attrs struct:
95af3a
- single_stride_log_num_of_bytes: log of size of each stride
95af3a
- single_wqe_log_num_of_strides: log of number of strides per WQE
95af3a
- two_byte_shift_en: When enabled, hardware pads 2 bytes of zeros
95af3a
  before writing the message to memory (e.g. for IP alignment).
95af3a
95af3a
Signed-off-by: Noa Osherovich <noaos@mellanox.com>
95af3a
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
95af3a
(cherry picked from commit 36a7ea92d214d35b69ad7e668cc21719b2a4d3ba)
95af3a
---
95af3a
 debian/ibverbs-providers.symbols |  2 ++
95af3a
 providers/mlx5/CMakeLists.txt    |  2 +-
95af3a
 providers/mlx5/libmlx5.map       |  5 +++
95af3a
 providers/mlx5/mlx5-abi.h        |  8 ++++-
95af3a
 providers/mlx5/mlx5dv.h          | 46 +++++++++++++++++++++++++-
95af3a
 providers/mlx5/verbs.c           | 71 ++++++++++++++++++++++++++++++++++++----
95af3a
 6 files changed, 125 insertions(+), 9 deletions(-)
95af3a
95af3a
diff --git a/debian/ibverbs-providers.symbols b/debian/ibverbs-providers.symbols
95af3a
index cb21dc5b..08ff9061 100644
95af3a
--- a/debian/ibverbs-providers.symbols
95af3a
+++ b/debian/ibverbs-providers.symbols
95af3a
@@ -8,8 +8,10 @@ libmlx5.so.1 ibverbs-providers #MINVER#
95af3a
  MLX5_1.0@MLX5_1.0 13
95af3a
  MLX5_1.1@MLX5_1.1 14
95af3a
  MLX5_1.2@MLX5_1.2 15
95af3a
+ MLX5_1.3@MLX5_1.3 16
95af3a
  mlx5dv_init_obj@MLX5_1.0 13
95af3a
  mlx5dv_init_obj@MLX5_1.2 15
95af3a
  mlx5dv_query_device@MLX5_1.0 13
95af3a
  mlx5dv_create_cq@MLX5_1.1 14
95af3a
  mlx5dv_set_context_attr@MLX5_1.2 15
95af3a
+ mlx5dv_create_wq@MLX5_1.3 16
95af3a
diff --git a/providers/mlx5/CMakeLists.txt b/providers/mlx5/CMakeLists.txt
95af3a
index ab6a42d8..88a406d9 100644
95af3a
--- a/providers/mlx5/CMakeLists.txt
95af3a
+++ b/providers/mlx5/CMakeLists.txt
95af3a
@@ -11,7 +11,7 @@ if (MLX5_MW_DEBUG)
95af3a
 endif()
95af3a
 
95af3a
 rdma_shared_provider(mlx5 libmlx5.map
95af3a
-  1 1.2.${PACKAGE_VERSION}
95af3a
+  1 1.3.${PACKAGE_VERSION}
95af3a
   buf.c
95af3a
   cq.c
95af3a
   dbrec.c
95af3a
diff --git a/providers/mlx5/libmlx5.map b/providers/mlx5/libmlx5.map
95af3a
index 09d886d1..b1402dc2 100644
95af3a
--- a/providers/mlx5/libmlx5.map
95af3a
+++ b/providers/mlx5/libmlx5.map
95af3a
@@ -17,3 +17,8 @@ MLX5_1.2 {
95af3a
 		mlx5dv_init_obj;
95af3a
 		mlx5dv_set_context_attr;
95af3a
 } MLX5_1.1;
95af3a
+
95af3a
+MLX5_1.3 {
95af3a
+	global:
95af3a
+		mlx5dv_create_wq;
95af3a
+} MLX5_1.2;
95af3a
diff --git a/providers/mlx5/mlx5-abi.h b/providers/mlx5/mlx5-abi.h
95af3a
index da7d54f2..5f0ecea1 100644
95af3a
--- a/providers/mlx5/mlx5-abi.h
95af3a
+++ b/providers/mlx5/mlx5-abi.h
95af3a
@@ -206,6 +206,10 @@ struct mlx5_create_qp_resp {
95af3a
 	__u32				uuar_index;
95af3a
 };
95af3a
 
95af3a
+enum mlx5_create_wq_comp_mask {
95af3a
+	MLX5_IB_CREATE_WQ_STRIDING_RQ =		1 << 0,
95af3a
+};
95af3a
+
95af3a
 struct mlx5_drv_create_wq {
95af3a
 	__u64		buf_addr;
95af3a
 	__u64		db_addr;
95af3a
@@ -214,7 +218,9 @@ struct mlx5_drv_create_wq {
95af3a
 	__u32		user_index;
95af3a
 	__u32		flags;
95af3a
 	__u32		comp_mask;
95af3a
-	__u32		reserved;
95af3a
+	__u32		single_stride_log_num_of_bytes;
95af3a
+	__u32		single_wqe_log_num_of_strides;
95af3a
+	__u32		two_byte_shift_en;
95af3a
 };
95af3a
 
95af3a
 struct mlx5_create_wq {
95af3a
diff --git a/providers/mlx5/mlx5dv.h b/providers/mlx5/mlx5dv.h
95af3a
index 0a7fe4d6..0b9b00df 100644
95af3a
--- a/providers/mlx5/mlx5dv.h
95af3a
+++ b/providers/mlx5/mlx5dv.h
95af3a
@@ -197,6 +197,43 @@ enum mlx5dv_obj_type {
95af3a
 	MLX5DV_OBJ_RWQ	= 1 << 3,
95af3a
 };
95af3a
 
95af3a
+enum mlx5dv_wq_init_attr_mask {
95af3a
+	MLX5DV_WQ_INIT_ATTR_MASK_STRIDING_RQ	= 1 << 0,
95af3a
+};
95af3a
+
95af3a
+struct mlx5dv_striding_rq_init_attr {
95af3a
+	uint32_t	single_stride_log_num_of_bytes;
95af3a
+	uint32_t	single_wqe_log_num_of_strides;
95af3a
+	uint8_t		two_byte_shift_en;
95af3a
+};
95af3a
+
95af3a
+struct mlx5dv_wq_init_attr {
95af3a
+	uint64_t				comp_mask; /* Use enum mlx5dv_wq_init_attr_mask */
95af3a
+	struct mlx5dv_striding_rq_init_attr	striding_rq_attrs;
95af3a
+};
95af3a
+
95af3a
+/*
95af3a
+ * This function creates a work queue object with extra properties
95af3a
+ * defined by mlx5dv_wq_init_attr struct.
95af3a
+ *
95af3a
+ * For each bit in the comp_mask, a field in mlx5dv_wq_init_attr
95af3a
+ * should follow.
95af3a
+ *
95af3a
+ * MLX5DV_WQ_INIT_ATTR_MASK_STRIDING_RQ: Create a work queue with
95af3a
+ * striding RQ capabilities.
95af3a
+ * - single_stride_log_num_of_bytes represents the size of each stride in the
95af3a
+ *   WQE and its value should be between min_single_stride_log_num_of_bytes
95af3a
+ *   and max_single_stride_log_num_of_bytes that are reported in
95af3a
+ *   mlx5dv_query_device.
95af3a
+ * - single_wqe_log_num_of_strides represents the number of strides in each WQE.
95af3a
+ *   Its value should be between min_single_wqe_log_num_of_strides and
95af3a
+ *   max_single_wqe_log_num_of_strides that are reported in mlx5dv_query_device.
95af3a
+ * - two_byte_shift_en: When enabled, hardware pads 2 bytes of zeroes
95af3a
+ *   before writing the message to memory (e.g. for IP alignment)
95af3a
+ */
95af3a
+struct ibv_wq *mlx5dv_create_wq(struct ibv_context *context,
95af3a
+				struct ibv_wq_init_attr *wq_init_attr,
95af3a
+				struct mlx5dv_wq_init_attr *mlx5_wq_attr);
95af3a
 /*
95af3a
  * This function will initialize mlx5dv_xxx structs based on supplied type.
95af3a
  * The information for initialization is taken from ibv_xx structs supplied
95af3a
@@ -302,7 +339,9 @@ struct mlx5_err_cqe {
95af3a
 };
95af3a
 
95af3a
 struct mlx5_cqe64 {
95af3a
-	uint8_t		rsvd0[17];
95af3a
+	uint8_t		rsvd0[2];
95af3a
+	__be16		wqe_id;
95af3a
+	uint8_t		rsvd4[13];
95af3a
 	uint8_t		ml_path;
95af3a
 	uint8_t		rsvd20[4];
95af3a
 	__be16		slid;
95af3a
@@ -412,6 +451,11 @@ struct mlx5_wqe_ctrl_seg {
95af3a
 	__be32		imm;
95af3a
 };
95af3a
 
95af3a
+struct mlx5_mprq_wqe {
95af3a
+	struct mlx5_wqe_srq_next_seg	nseg;
95af3a
+	struct mlx5_wqe_data_seg	dseg;
95af3a
+};
95af3a
+
95af3a
 struct mlx5_wqe_av {
95af3a
 	union {
95af3a
 		struct {
95af3a
diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c
95af3a
index e9414c64..15c0d4ed 100644
95af3a
--- a/providers/mlx5/verbs.c
95af3a
+++ b/providers/mlx5/verbs.c
95af3a
@@ -919,21 +919,36 @@ static int mlx5_calc_sq_size(struct mlx5_context *ctx,
95af3a
 	return wq_size;
95af3a
 }
95af3a
 
95af3a
+enum {
95af3a
+	DV_CREATE_WQ_SUPPORTED_COMP_MASK = MLX5DV_WQ_INIT_ATTR_MASK_STRIDING_RQ
95af3a
+};
95af3a
+
95af3a
 static int mlx5_calc_rwq_size(struct mlx5_context *ctx,
95af3a
 			      struct mlx5_rwq *rwq,
95af3a
-			      struct ibv_wq_init_attr *attr)
95af3a
+			      struct ibv_wq_init_attr *attr,
95af3a
+			      struct mlx5dv_wq_init_attr *mlx5wq_attr)
95af3a
 {
95af3a
 	size_t wqe_size;
95af3a
 	int wq_size;
95af3a
 	uint32_t num_scatter;
95af3a
+	int is_mprq = 0;
95af3a
 	int scat_spc;
95af3a
 
95af3a
 	if (!attr->max_wr)
95af3a
 		return -EINVAL;
95af3a
+	if (mlx5wq_attr) {
95af3a
+		if (!check_comp_mask(mlx5wq_attr->comp_mask,
95af3a
+				     DV_CREATE_WQ_SUPPORTED_COMP_MASK))
95af3a
+			return -EINVAL;
95af3a
+
95af3a
+		is_mprq = !!(mlx5wq_attr->comp_mask &
95af3a
+			     MLX5DV_WQ_INIT_ATTR_MASK_STRIDING_RQ);
95af3a
+	}
95af3a
 
95af3a
 	/* TBD: check caps for RQ */
95af3a
 	num_scatter = max_t(uint32_t, attr->max_sge, 1);
95af3a
-	wqe_size = sizeof(struct mlx5_wqe_data_seg) * num_scatter;
95af3a
+	wqe_size = sizeof(struct mlx5_wqe_data_seg) * num_scatter +
95af3a
+		sizeof(struct mlx5_wqe_srq_next_seg) * is_mprq;
95af3a
 
95af3a
 	if (rwq->wq_sig)
95af3a
 		wqe_size += sizeof(struct mlx5_rwqe_sig);
95af3a
@@ -948,7 +963,8 @@ static int mlx5_calc_rwq_size(struct mlx5_context *ctx,
95af3a
 	rwq->rq.wqe_shift = mlx5_ilog2(wqe_size);
95af3a
 	rwq->rq.max_post = 1 << mlx5_ilog2(wq_size / wqe_size);
95af3a
 	scat_spc = wqe_size -
95af3a
-		((rwq->wq_sig) ? sizeof(struct mlx5_rwqe_sig) : 0);
95af3a
+		((rwq->wq_sig) ? sizeof(struct mlx5_rwqe_sig) : 0) -
95af3a
+		is_mprq * sizeof(struct mlx5_wqe_srq_next_seg);
95af3a
 	rwq->rq.max_gs = scat_spc / sizeof(struct mlx5_wqe_data_seg);
95af3a
 	return wq_size;
95af3a
 }
95af3a
@@ -2066,8 +2082,9 @@ static int mlx5_alloc_rwq_buf(struct ibv_context *context,
95af3a
 	return 0;
95af3a
 }
95af3a
 
95af3a
-struct ibv_wq *mlx5_create_wq(struct ibv_context *context,
95af3a
-			      struct ibv_wq_init_attr *attr)
95af3a
+static struct ibv_wq *create_wq(struct ibv_context *context,
95af3a
+			 struct ibv_wq_init_attr *attr,
95af3a
+			 struct mlx5dv_wq_init_attr *mlx5wq_attr)
95af3a
 {
95af3a
 	struct mlx5_create_wq		cmd;
95af3a
 	struct mlx5_create_wq_resp		resp;
95af3a
@@ -2092,7 +2109,7 @@ struct ibv_wq *mlx5_create_wq(struct ibv_context *context,
95af3a
 	if (rwq->wq_sig)
95af3a
 		cmd.drv.flags = MLX5_RWQ_FLAG_SIGNATURE;
95af3a
 
95af3a
-	ret = mlx5_calc_rwq_size(ctx, rwq, attr);
95af3a
+	ret = mlx5_calc_rwq_size(ctx, rwq, attr, mlx5wq_attr);
95af3a
 	if (ret < 0) {
95af3a
 		errno = -ret;
95af3a
 		goto err;
95af3a
@@ -2126,6 +2143,35 @@ struct ibv_wq *mlx5_create_wq(struct ibv_context *context,
95af3a
 	}
95af3a
 
95af3a
 	cmd.drv.user_index = usr_idx;
95af3a
+
95af3a
+	if (mlx5wq_attr) {
95af3a
+		if (mlx5wq_attr->comp_mask & MLX5DV_WQ_INIT_ATTR_MASK_STRIDING_RQ) {
95af3a
+			if ((mlx5wq_attr->striding_rq_attrs.single_stride_log_num_of_bytes <
95af3a
+			    ctx->striding_rq_caps.min_single_stride_log_num_of_bytes) ||
95af3a
+			    (mlx5wq_attr->striding_rq_attrs.single_stride_log_num_of_bytes >
95af3a
+			     ctx->striding_rq_caps.max_single_stride_log_num_of_bytes)) {
95af3a
+				errno = EINVAL;
95af3a
+				goto err_create;
95af3a
+			}
95af3a
+
95af3a
+			if ((mlx5wq_attr->striding_rq_attrs.single_wqe_log_num_of_strides <
95af3a
+			     ctx->striding_rq_caps.min_single_wqe_log_num_of_strides) ||
95af3a
+			    (mlx5wq_attr->striding_rq_attrs.single_wqe_log_num_of_strides >
95af3a
+			     ctx->striding_rq_caps.max_single_wqe_log_num_of_strides)) {
95af3a
+				errno = EINVAL;
95af3a
+				goto err_create;
95af3a
+			}
95af3a
+
95af3a
+			cmd.drv.single_stride_log_num_of_bytes =
95af3a
+				mlx5wq_attr->striding_rq_attrs.single_stride_log_num_of_bytes;
95af3a
+			cmd.drv.single_wqe_log_num_of_strides =
95af3a
+				mlx5wq_attr->striding_rq_attrs.single_wqe_log_num_of_strides;
95af3a
+			cmd.drv.two_byte_shift_en =
95af3a
+				mlx5wq_attr->striding_rq_attrs.two_byte_shift_en;
95af3a
+			cmd.drv.comp_mask |= MLX5_IB_CREATE_WQ_STRIDING_RQ;
95af3a
+		}
95af3a
+	}
95af3a
+
95af3a
 	err = ibv_cmd_create_wq(context, attr, &rwq->wq, &cmd.ibv_cmd,
95af3a
 				sizeof(cmd.ibv_cmd),
95af3a
 				sizeof(cmd),
95af3a
@@ -2151,6 +2197,19 @@ err:
95af3a
 	return NULL;
95af3a
 }
95af3a
 
95af3a
+struct ibv_wq *mlx5_create_wq(struct ibv_context *context,
95af3a
+			      struct ibv_wq_init_attr *attr)
95af3a
+{
95af3a
+	return create_wq(context, attr, NULL);
95af3a
+}
95af3a
+
95af3a
+struct ibv_wq *mlx5dv_create_wq(struct ibv_context *context,
95af3a
+				struct ibv_wq_init_attr *attr,
95af3a
+				struct mlx5dv_wq_init_attr *mlx5_wq_attr)
95af3a
+{
95af3a
+	return create_wq(context, attr, mlx5_wq_attr);
95af3a
+}
95af3a
+
95af3a
 int mlx5_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *attr)
95af3a
 {
95af3a
 	struct mlx5_modify_wq	cmd = {};
95af3a
-- 
95af3a
2.12.1
95af3a