diff mbox

[v1,libmlx4,2/7] Add support for ibv_create_cq_ex

Message ID 1445965737-14187-3-git-send-email-matanb@mellanox.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Matan Barak Oct. 27, 2015, 5:08 p.m. UTC
Add an extension verb mlx4_create_cq_ex that follows the
standard extension verb mechanism.
This function is similar to mlx4_create_cq but supports the
extension verbs functions and stores the creation flags
for later use (for example, timestamp flag is used in poll_cq).
The function fails if the user passes unsupported WC attributes.

Signed-off-by: Matan Barak <matanb@mellanox.com>
---
 src/mlx4-abi.h |  12 ++++++
 src/mlx4.c     |   1 +
 src/mlx4.h     |   3 ++
 src/verbs.c    | 117 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 4 files changed, 117 insertions(+), 16 deletions(-)
diff mbox

Patch

diff --git a/src/mlx4-abi.h b/src/mlx4-abi.h
index b348ce3..9b765e4 100644
--- a/src/mlx4-abi.h
+++ b/src/mlx4-abi.h
@@ -72,12 +72,24 @@  struct mlx4_create_cq {
 	__u64				db_addr;
 };
 
+struct mlx4_create_cq_ex {
+	struct ibv_create_cq_ex		ibv_cmd;
+	__u64				buf_addr;
+	__u64				db_addr;
+};
+
 struct mlx4_create_cq_resp {
 	struct ibv_create_cq_resp	ibv_resp;
 	__u32				cqn;
 	__u32				reserved;
 };
 
+struct mlx4_create_cq_resp_ex {
+	struct ibv_create_cq_resp_ex	ibv_resp;
+	__u32				cqn;
+	__u32				reserved;
+};
+
 struct mlx4_resize_cq {
 	struct ibv_resize_cq		ibv_cmd;
 	__u64				buf_addr;
diff --git a/src/mlx4.c b/src/mlx4.c
index d41dff0..9cfd013 100644
--- a/src/mlx4.c
+++ b/src/mlx4.c
@@ -208,6 +208,7 @@  static int mlx4_init_context(struct verbs_device *v_device,
 	verbs_set_ctx_op(verbs_ctx, ibv_create_flow, ibv_cmd_create_flow);
 	verbs_set_ctx_op(verbs_ctx, ibv_destroy_flow, ibv_cmd_destroy_flow);
 	verbs_set_ctx_op(verbs_ctx, query_device_ex, mlx4_query_device_ex);
+	verbs_set_ctx_op(verbs_ctx, create_cq_ex, mlx4_create_cq_ex);
 
 	return 0;
 
diff --git a/src/mlx4.h b/src/mlx4.h
index 0f643bc..91eb79c 100644
--- a/src/mlx4.h
+++ b/src/mlx4.h
@@ -222,6 +222,7 @@  struct mlx4_cq {
 	uint32_t		       *arm_db;
 	int				arm_sn;
 	int				cqe_size;
+	int				creation_flags;
 };
 
 struct mlx4_srq {
@@ -402,6 +403,8 @@  int mlx4_dereg_mr(struct ibv_mr *mr);
 struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe,
 			       struct ibv_comp_channel *channel,
 			       int comp_vector);
+struct ibv_cq *mlx4_create_cq_ex(struct ibv_context *context,
+				 struct ibv_create_cq_attr_ex *cq_attr);
 int mlx4_alloc_cq_buf(struct mlx4_device *dev, struct mlx4_buf *buf, int nent,
 		      int entry_size);
 int mlx4_resize_cq(struct ibv_cq *cq, int cqe);
diff --git a/src/verbs.c b/src/verbs.c
index e93114b..3290b86 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -272,19 +272,69 @@  int align_queue_size(int req)
 	return nent;
 }
 
-struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe,
-			       struct ibv_comp_channel *channel,
-			       int comp_vector)
+enum cmd_type {
+	MLX4_CMD_TYPE_BASIC,
+	MLX4_CMD_TYPE_EXTENDED
+};
+
+enum {
+	CREATE_CQ_SUPPORTED_COMP_MASK = IBV_CREATE_CQ_ATTR_FLAGS
+};
+
+enum {
+	CREATE_CQ_SUPPORTED_FLAGS = IBV_CREATE_CQ_ATTR_COMPLETION_TIMESTAMP
+};
+
+enum {
+	CREATE_CQ_SUPPORTED_WC_FLAGS = IBV_WC_STANDARD_FLAGS
+};
+
+static struct ibv_cq *create_cq(struct ibv_context *context,
+				struct ibv_create_cq_attr_ex *cq_attr,
+				enum cmd_type cmd_type)
 {
-	struct mlx4_create_cq      cmd;
-	struct mlx4_create_cq_resp resp;
-	struct mlx4_cq		  *cq;
-	int			   ret;
-	struct mlx4_context       *mctx = to_mctx(context);
+	struct mlx4_create_cq		cmd;
+	struct mlx4_create_cq_ex	cmd_e;
+	struct mlx4_create_cq_resp	resp;
+	struct mlx4_create_cq_resp_ex	resp_e;
+	struct mlx4_cq			*cq;
+	int				ret;
+	struct mlx4_context		*mctx = to_mctx(context);
+	struct ibv_create_cq_attr_ex	cq_attr_e;
+	int cqe;
 
 	/* Sanity check CQ size before proceeding */
-	if (cqe > 0x3fffff)
+	if (cq_attr->cqe > 0x3fffff)
+		return NULL;
+
+	if (cq_attr->comp_mask & ~CREATE_CQ_SUPPORTED_COMP_MASK) {
+		errno = EINVAL;
 		return NULL;
+	}
+
+	if (cq_attr->comp_mask & IBV_CREATE_CQ_ATTR_FLAGS &&
+	    cq_attr->flags & ~CREATE_CQ_SUPPORTED_FLAGS) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	if (cq_attr->wc_flags & ~CREATE_CQ_SUPPORTED_WC_FLAGS) {
+		errno = ENOTSUP;
+		return NULL;
+	}
+
+	if (!(cq_attr->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP) !=
+	    !(cq_attr->comp_mask & IBV_CREATE_CQ_ATTR_FLAGS &&
+	      cq_attr->flags & IBV_CREATE_CQ_ATTR_COMPLETION_TIMESTAMP)) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	if (cq_attr->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP &&
+	    cq_attr->wc_flags & (IBV_WC_EX_WITH_SL | IBV_WC_EX_WITH_SLID)) {
+		errno = EOPNOTSUPP;
+		return NULL;
+	}
 
 	cq = malloc(sizeof *cq);
 	if (!cq)
@@ -295,9 +345,11 @@  struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe,
 	if (pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE))
 		goto err;
 
-	cqe = align_queue_size(cqe + 1);
+	cq_attr_e = *cq_attr;
+	cqe = align_queue_size(cq_attr->cqe + 1);
 
-	if (mlx4_alloc_cq_buf(to_mdev(context->device), &cq->buf, cqe, mctx->cqe_size))
+	if (mlx4_alloc_cq_buf(to_mdev(context->device), &cq->buf, cqe,
+			      mctx->cqe_size))
 		goto err;
 
 	cq->cqe_size = mctx->cqe_size;
@@ -310,15 +362,31 @@  struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe,
 	cq->arm_sn     = 1;
 	*cq->set_ci_db = 0;
 
-	cmd.buf_addr = (uintptr_t) cq->buf.buf;
-	cmd.db_addr  = (uintptr_t) cq->set_ci_db;
+	if (cmd_type == MLX4_CMD_TYPE_BASIC) {
+		cmd.buf_addr = (uintptr_t)cq->buf.buf;
+		cmd.db_addr  = (uintptr_t)cq->set_ci_db;
+
+		ret = ibv_cmd_create_cq(context, cqe - 1,
+					cq_attr_e.channel, cq_attr_e.comp_vector,
+					&cq->ibv_cq, &cmd.ibv_cmd, sizeof(cmd),
+					&resp.ibv_resp, sizeof(resp));
+	} else {
+		cmd_e.buf_addr = (uintptr_t)cq->buf.buf;
+		cmd_e.db_addr  = (uintptr_t)cq->set_ci_db;
+
+		cq_attr_e.cqe = cqe - 1;
+		ret = ibv_cmd_create_cq_ex(context, &cq_attr_e, &cq->ibv_cq,
+					   &cmd_e.ibv_cmd,
+					   sizeof(cmd_e.ibv_cmd), sizeof(cmd_e),
+					   &resp_e.ibv_resp,
+					   sizeof(resp_e.ibv_resp),
+					   sizeof(resp_e));
+	}
 
-	ret = ibv_cmd_create_cq(context, cqe - 1, channel, comp_vector,
-				&cq->ibv_cq, &cmd.ibv_cmd, sizeof cmd,
-				&resp.ibv_resp, sizeof resp);
 	if (ret)
 		goto err_db;
 
+	cq->creation_flags = cmd_e.ibv_cmd.flags;
 	cq->cqn = resp.cqn;
 
 	return &cq->ibv_cq;
@@ -335,6 +403,23 @@  err:
 	return NULL;
 }
 
+struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe,
+			      struct ibv_comp_channel *channel,
+			      int comp_vector)
+{
+	struct ibv_create_cq_attr_ex attr = {.cqe = cqe, .channel = channel,
+					     .comp_vector = comp_vector,
+					     .wc_flags = IBV_WC_STANDARD_FLAGS};
+
+	return create_cq(context, &attr, MLX4_CMD_TYPE_BASIC);
+}
+
+struct ibv_cq *mlx4_create_cq_ex(struct ibv_context *context,
+				 struct ibv_create_cq_attr_ex *cq_attr)
+{
+	return create_cq(context, cq_attr, MLX4_CMD_TYPE_EXTENDED);
+}
+
 int mlx4_resize_cq(struct ibv_cq *ibcq, int cqe)
 {
 	struct mlx4_cq *cq = to_mcq(ibcq);