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

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