[ofa-general] [PATCH 3/3 v2] ib/uverbs: add support for create_qp_expanded in uverbs

ronli at voltaire.com ronli at voltaire.com
Mon Jul 21 13:27:35 PDT 2008


This patch adds support for create_qp_expanded
to the uverbs.
It uses the reserved bitmap in ib_uverbs_create_qp
to transfer the new creation flags from the user space
to the kernel.

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

Changes in v2:
Minimized code duplication by adding the function
ib_uverbs_create_qp_common.

LSO now can not be activated through user space.

diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index b55f0d7..ae9f9a8 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -214,6 +214,7 @@ IB_UVERBS_DECLARE_CMD(modify_xrc_rcv_qp);
 IB_UVERBS_DECLARE_CMD(query_xrc_rcv_qp);
 IB_UVERBS_DECLARE_CMD(reg_xrc_rcv_qp);
 IB_UVERBS_DECLARE_CMD(unreg_xrc_rcv_qp);
+IB_UVERBS_DECLARE_CMD(create_qp_expanded);


 #endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 4402a07..838e28a 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1029,11 +1029,11 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
 	return in_len;
 }

-ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
-			    const char __user *buf, int in_len,
-			    int out_len)
+static ssize_t ib_uverbs_create_qp_common(struct ib_uverbs_file *file,
+					const char __user *buf, int in_len,
+					int out_len, int expanded)
 {
-	struct ib_uverbs_create_qp      cmd;
+	struct ib_uverbs_create_qp cmd;
 	struct ib_uverbs_create_qp_resp resp;
 	struct ib_udata                 udata;
 	struct ib_uqp_object           *obj;
@@ -1078,7 +1078,6 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
 		goto err_put;
 	}

-	attr.create_flags  = 0;
 	attr.event_handler = ib_uverbs_qp_event_handler;
 	attr.qp_context    = file;
 	attr.send_cq       = scq;
@@ -1087,7 +1086,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
 	attr.sq_sig_type   = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
 	attr.qp_type       = cmd.qp_type;
 	attr.xrc_domain    = xrcd;
-	attr.create_flags  = 0;
+	attr.create_flags  = expanded ? cmd.reserved : 0;

 	attr.cap.max_send_wr     = cmd.max_send_wr;
 	attr.cap.max_recv_wr     = cmd.max_recv_wr;
@@ -1184,6 +1183,20 @@ err_put:
 	return ret;
 }

+ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
+				const char __user *buf, int in_len,
+				int out_len)
+{
+	return ib_uverbs_create_qp_common(file, buf, in_len, out_len, 0);
+}
+
+ssize_t ib_uverbs_create_qp_expanded(struct ib_uverbs_file *file,
+			    const char __user *buf, int in_len,
+			    int out_len)
+{
+	return ib_uverbs_create_qp_common(file, buf, in_len, out_len, 1);
+}
+
 ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
 			   const char __user *buf, int in_len,
 			   int out_len)
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 1a96c35..cb435be 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -117,6 +117,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
 	[IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP]	= ib_uverbs_query_xrc_rcv_qp,
 	[IB_USER_VERBS_CMD_REG_XRC_RCV_QP]	= ib_uverbs_reg_xrc_rcv_qp,
 	[IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP]	= ib_uverbs_unreg_xrc_rcv_qp,
+	[IB_USER_VERBS_CMD_CREATE_QP_EXPANDED]	= ib_uverbs_create_qp_expanded,
 };

 static struct vfsmount *uverbs_event_mnt;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 030f696..f954533 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -728,7 +728,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
 			(1ull << IB_USER_VERBS_CMD_MODIFY_XRC_RCV_QP)	|
 			(1ull << IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP)	|
 			(1ull << IB_USER_VERBS_CMD_REG_XRC_RCV_QP)	|
-			(1ull << IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP);
+			(1ull << IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP)	|
+			(1ull << IB_USER_VERBS_CMD_CREATE_QP_EXPANDED);
 	}

 	if (init_node_data(ibdev))
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 0d3f770..29e5ce1 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -518,9 +518,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
 	} else {
 		qp->sq_no_prefetch = 0;

-		if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
-			qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
-
 		if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)
 			qp->flags |= MLX4_IB_QP_LSO;

@@ -559,6 +556,10 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
 		}
 	}

+	if (init_attr->create_flags &
+		IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
+			qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
+
 	err = mlx4_qp_alloc(dev->dev, sqpn, &qp->mqp);
 	if (err)
 		goto err_wrid;
@@ -705,8 +706,11 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
 					IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK))
 		return ERR_PTR(-EINVAL);

-	if (init_attr->create_flags &&
-	    (pd->uobject || init_attr->qp_type != IB_QPT_UD))
+	if (init_attr->create_flags && init_attr->qp_type != IB_QPT_UD)
+		return ERR_PTR(-EINVAL);
+
+	if ((init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) &&
+								pd->uobject)
 		return ERR_PTR(-EINVAL);

 	switch (init_attr->qp_type) {
@@ -722,6 +726,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
 			return ERR_PTR(-ENOMEM);

 		err = create_qp_common(dev, pd, init_attr, udata, 0, qp);
+
 		if (err) {
 			kfree(qp);
 			return ERR_PTR(err);
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index 0df90d8..c744bca 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -90,6 +90,7 @@ enum {
 	IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP,
 	IB_USER_VERBS_CMD_REG_XRC_RCV_QP,
 	IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP,
+	IB_USER_VERBS_CMD_CREATE_QP_EXPANDED,
 };

 /*



More information about the general mailing list