[ofa-general] [PATCH 2/4]libmlx4: add support for new verb create_qp_flags

Ron Livne ronli at voltaire.com
Thu Dec 11 01:02:24 PST 2008


Adds support for the new verb: create_qp_expanded in libmlx4.

Signed-off-by: Ron Livne <ronli at voltaire.com>

diff --git a/configure.in b/configure.in
index 25f27f7..10f61eb 100644
--- a/configure.in
+++ b/configure.in
@@ -42,7 +42,9 @@ AC_CHECK_HEADER(valgrind/memcheck.h,
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 AC_CHECK_SIZEOF(long)
-
+AC_CHECK_MEMBER(struct ibv_context.more_ops,
+    [AC_DEFINE([HAVE_IBV_MORE_OPS], 1, [Define to 1 if more_ops is a member of ibv_context])],,
+    [#include <infiniband/verbs.h>])
 dnl Checks for library functions
 AC_CHECK_FUNC(ibv_read_sysfs_file, [],
     AC_MSG_ERROR([ibv_read_sysfs_file() not found.  libmlx4 requires libibverbs >= 1.0.3.]))
diff --git a/src/mlx4-abi.h b/src/mlx4-abi.h
index 20a40c9..4f0ad13 100644
--- a/src/mlx4-abi.h
+++ b/src/mlx4-abi.h
@@ -90,4 +90,14 @@ struct mlx4_create_qp {
 	__u8				reserved[5];
 };

+struct mlx4_create_qp_flags {
+	struct ibv_create_qp_flags	ibv_cmd;
+	__u64                           buf_addr;
+	__u64                           db_addr;
+	__u8                            log_sq_bb_count;
+	__u8                            log_sq_stride;
+	__u8                            sq_no_prefetch;
+	__u8                            reserved[5];
+};
+
 #endif /* MLX4_ABI_H */
diff --git a/src/mlx4.c b/src/mlx4.c
index 34ece39..04f453f 100644
--- a/src/mlx4.c
+++ b/src/mlx4.c
@@ -68,6 +68,12 @@ struct {
 	HCA(MELLANOX, 0x673c),	/* MT25408 "Hermon" QDR PCIe gen2 */
 };

+#ifdef HAVE_IBV_MORE_OPS
+static struct ibv_more_ops mlx4_more_ops = {
+	.create_qp_flags = mlx4_create_qp_flags,
+};
+#endif
+
 static struct ibv_context_ops mlx4_ctx_ops = {
 	.query_device  = mlx4_query_device,
 	.query_port    = mlx4_query_port,
@@ -156,6 +162,10 @@ static struct ibv_context *mlx4_alloc_context(struct ibv_device *ibdev, int cmd_

 	context->ibv_ctx.ops = mlx4_ctx_ops;

+#ifdef HAVE_IBV_MORE_OPS
+	context->ibv_ctx.more_ops = &mlx4_more_ops;
+#endif
+
 	return &context->ibv_ctx;

 err_free:
diff --git a/src/mlx4.h b/src/mlx4.h
index 827a201..29c46a5 100644
--- a/src/mlx4.h
+++ b/src/mlx4.h
@@ -335,6 +335,11 @@ int mlx4_post_srq_recv(struct ibv_srq *ibsrq,
 		       struct ibv_recv_wr **bad_wr);

 struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr);
+#ifdef HAVE_IBV_MORE_OPS
+struct ibv_qp *mlx4_create_qp_flags(struct ibv_pd *pd,
+				struct ibv_qp_init_attr *attr,
+				uint32_t create_flags);
+#endif
 int mlx4_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 		   enum ibv_qp_attr_mask attr_mask,
 		   struct ibv_qp_init_attr *init_attr);
diff --git a/src/verbs.c b/src/verbs.c
index cc179a0..b67ea79 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -384,13 +384,10 @@ int mlx4_destroy_srq(struct ibv_srq *srq)
 	return 0;
 }

-struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
+static struct mlx4_qp *mlx4_create_qp_common(struct ibv_pd *pd,
+				struct ibv_qp_init_attr *attr,
+				struct mlx4_qp *qp)
 {
-	struct mlx4_create_qp     cmd;
-	struct ibv_create_qp_resp resp;
-	struct mlx4_qp		 *qp;
-	int			  ret;
-
 	/* Sanity check QP size before proceeding */
 	if (attr->cap.max_send_wr     > 65536 ||
 	    attr->cap.max_recv_wr     > 65536 ||
@@ -439,6 +436,31 @@ struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
 		*qp->db = 0;
 	}

+	return qp;
+
+err_free:
+	free(qp->sq.wrid);
+	if (qp->rq.wqe_cnt)
+		free(qp->rq.wrid);
+	mlx4_free_buf(&qp->buf);
+
+err:
+	free(qp);
+
+	return NULL;
+}
+
+struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
+{
+	struct mlx4_create_qp     cmd;
+	struct ibv_create_qp_resp resp;
+	struct mlx4_qp		 *qp;
+	int			  ret;
+
+	qp = mlx4_create_qp_common(pd, attr, qp);
+	if (qp == NULL)
+		return NULL;
+
 	cmd.buf_addr	    = (uintptr_t) qp->buf.buf;
 	if (attr->srq)
 		cmd.db_addr = 0;
@@ -484,13 +506,78 @@ err_rq_db:
 	if (!attr->srq)
 		mlx4_free_db(to_mctx(pd->context), MLX4_DB_TYPE_RQ, qp->db);

-err_free:
 	free(qp->sq.wrid);
 	if (qp->rq.wqe_cnt)
 		free(qp->rq.wrid);
 	mlx4_free_buf(&qp->buf);

-err:
+	free(qp);
+
+	return NULL;
+}
+
+struct ibv_qp *mlx4_create_qp_flags(struct ibv_pd *pd,
+				struct ibv_qp_init_attr *attr,
+				uint32_t create_flags)
+{
+	struct mlx4_create_qp_flags cmd;
+	struct ibv_create_qp_resp resp;
+	struct mlx4_qp		 *qp;
+	int			  ret;
+
+	qp = mlx4_create_qp_common(pd, attr, qp);
+
+	cmd.buf_addr	    = (uintptr_t) qp->buf.buf;
+	if (attr->srq)
+		cmd.db_addr = 0;
+	else
+		cmd.db_addr = (uintptr_t) qp->db;
+	cmd.log_sq_stride   = qp->sq.wqe_shift;
+	for (cmd.log_sq_bb_count = 0;
+	     qp->sq.wqe_cnt > 1 << cmd.log_sq_bb_count;
+	     ++cmd.log_sq_bb_count)
+		; /* nothing */
+	cmd.sq_no_prefetch = 0;	/* OK for ABI 2: just a reserved field */
+	memset(cmd.reserved, 0, sizeof cmd.reserved);
+
+	pthread_mutex_lock(&to_mctx(pd->context)->qp_table_mutex);
+
+	ret = ibv_cmd_create_qp_flags(pd, &qp->ibv_qp, attr, create_flags,
+				&cmd.ibv_cmd, sizeof cmd,
+				&resp, sizeof resp);
+	if (ret)
+		goto err_rq_db;
+
+	ret = mlx4_store_qp(to_mctx(pd->context), qp->ibv_qp.qp_num, qp);
+	if (ret)
+		goto err_destroy;
+	pthread_mutex_unlock(&to_mctx(pd->context)->qp_table_mutex);
+
+	qp->rq.wqe_cnt = qp->rq.max_post = attr->cap.max_recv_wr;
+	qp->rq.max_gs  = attr->cap.max_recv_sge;
+	mlx4_set_sq_sizes(qp, &attr->cap, attr->qp_type);
+
+	qp->doorbell_qpn    = htonl(qp->ibv_qp.qp_num << 8);
+	if (attr->sq_sig_all)
+		qp->sq_signal_bits = htonl(MLX4_WQE_CTRL_CQ_UPDATE);
+	else
+		qp->sq_signal_bits = 0;
+
+	return &qp->ibv_qp;
+
+err_destroy:
+	ibv_cmd_destroy_qp(&qp->ibv_qp);
+
+err_rq_db:
+	pthread_mutex_unlock(&to_mctx(pd->context)->qp_table_mutex);
+	if (!attr->srq)
+		mlx4_free_db(to_mctx(pd->context), MLX4_DB_TYPE_RQ, qp->db);
+
+	free(qp->sq.wrid);
+	if (qp->rq.wqe_cnt)
+		free(qp->rq.wrid);
+	mlx4_free_buf(&qp->buf);
+
 	free(qp);

 	return NULL;



More information about the general mailing list