[ewg] ***SPAM*** [PATCH 2/2]libmlx4: add create_qp_expanded

Ron Livne ronli at voltaire.com
Mon Aug 11 18:36:40 PDT 2008


Adds support for the new verb: create_qp_expanded
in libmlx4.

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

diff --git a/src/mlx4-abi.h b/src/mlx4-abi.h
index 1b1253c..729f4ee 100644
--- a/src/mlx4-abi.h
+++ b/src/mlx4-abi.h
@@ -98,6 +98,16 @@ struct mlx4_create_qp {
 	__u8				reserved[5];
 };

+struct mlx4_create_qp_expanded {
+	struct ibv_create_qp_expanded	ibv_cmd;
+	__u64                           buf_addr;
+	__u64                           db_addr;
+	__u8                            log_sq_bb_count;
+	__u8                            log_sq_stride;
+	__u8                            sq_no_prefetch;
+	__u8                            reserved[5];
+};
+
 #ifdef HAVE_IBV_XRC_OPS
 struct mlx4_open_xrc_domain_resp {
 	struct ibv_open_xrc_domain_resp	ibv_resp;
diff --git a/src/mlx4.c b/src/mlx4.c
index e5ded78..e218a40 100644
--- a/src/mlx4.c
+++ b/src/mlx4.c
@@ -79,6 +79,7 @@ static struct ibv_more_ops mlx4_more_ops = {
 	.query_xrc_rcv_qp = mlx4_query_xrc_rcv_qp,
 	.reg_xrc_rcv_qp   = mlx4_reg_xrc_rcv_qp,
 	.unreg_xrc_rcv_qp = mlx4_unreg_xrc_rcv_qp,
+	.create_qp_expanded = mlx4_create_qp_expanded,
 #endif
 };
 #endif
diff --git a/src/mlx4.h b/src/mlx4.h
index 6307a2d..8042135 100644
--- a/src/mlx4.h
+++ b/src/mlx4.h
@@ -444,6 +444,9 @@ int mlx4_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
 			uint32_t xrc_qp_num);
 int mlx4_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
 			uint32_t xrc_qp_num);
+struct ibv_qp *mlx4_create_qp_expanded(struct ibv_pd *pd,
+					struct ibv_qp_init_attr *attr,
+					uint32_t create_flags);
 #endif


diff --git a/src/verbs.c b/src/verbs.c
index 8261eae..1f46d19 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -402,15 +402,11 @@ int mlx4_destroy_srq(struct ibv_srq *ibsrq)
 	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_context *context)
 {
-	struct mlx4_create_qp     cmd;
-	struct ibv_create_qp_resp resp;
-	struct mlx4_qp		 *qp;
-	int			  ret;
-	struct mlx4_context	 *context = to_mctx(pd->context);
-
-
 	/* Sanity check QP size before proceeding */
 	if (attr->cap.max_send_wr     > context->max_qp_wr ||
 	    attr->cap.max_recv_wr     > context->max_qp_wr ||
@@ -419,10 +415,6 @@ struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
 	    attr->cap.max_inline_data > 1024)
 		return NULL;

-	qp = malloc(sizeof *qp);
-	if (!qp)
-		return NULL;
-
 	mlx4_calc_sq_wqe_size(&attr->cap, attr->qp_type, qp);

 	/*
@@ -458,18 +450,46 @@ 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;
+	struct mlx4_context	*context = to_mctx(pd->context);
+
+	qp = malloc(sizeof *qp);
+	if (!qp)
+		return NULL;
+	qp = mlx4_create_qp_common(pd, attr, qp, context);
+	if (!qp)
+		return NULL;

-	cmd.buf_addr	    = (uintptr_t) qp->buf.buf;
+	cmd.buf_addr        = (uintptr_t) qp->buf.buf;
 	if (attr->srq || attr->qp_type == IBV_QPT_XRC)
 		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)
+		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 */
+	cmd.sq_no_prefetch = 0; /* OK for ABI 2: just a reserved field */
 	memset(cmd.reserved, 0, sizeof cmd.reserved);

 	ret = ibv_cmd_create_qp(pd, &qp->ibv_qp, attr, &cmd.ibv_cmd, sizeof cmd,
@@ -506,13 +526,86 @@ err_rq_db:
 	if (!attr->srq && attr->qp_type != IBV_QPT_XRC)
 		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_expanded(struct ibv_pd *pd,
+					struct ibv_qp_init_attr *attr,
+					uint32_t create_flags)
+{
+	struct mlx4_create_qp_expanded	cmd;
+	struct ibv_create_qp_resp resp;
+	struct mlx4_qp		*qp;
+	int			ret;
+	struct mlx4_context	*context = to_mctx(pd->context);
+
+	qp = malloc(sizeof *qp);
+	if (!qp)
+		return NULL;
+	qp = mlx4_create_qp_common(pd, attr, qp, context);
+	if (!qp)
+		return NULL;
+
+	cmd.buf_addr        = (uintptr_t) qp->buf.buf;
+	if (attr->srq || attr->qp_type == IBV_QPT_XRC)
+		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);
+
+	ret = ibv_cmd_create_qp_expanded(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;
+
+	qp->rq.wqe_cnt = attr->cap.max_recv_wr;
+	qp->rq.max_gs  = attr->cap.max_recv_sge;
+
+	/* adjust rq maxima to not exceed reported device maxima */
+	attr->cap.max_recv_wr = min(context->max_qp_wr, attr->cap.max_recv_wr);
+	attr->cap.max_recv_sge = min(context->max_sge, attr->cap.max_recv_sge);
+
+	qp->rq.max_post = attr->cap.max_recv_wr;
+	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:
+	if (!attr->srq && attr->qp_type != IBV_QPT_XRC)
+		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 ewg mailing list