All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] RDMA/rxe: Implement extended verbs APIs
@ 2020-11-06 23:03 Bob Pearson
  2020-11-06 23:03 ` [PATCH 1/2] RDMA/rxe: Exchange capabilities with provider Bob Pearson
  2020-11-06 23:03 ` [PATCH 2/2] RDMA/rxe: Implement the create_cq_ex verb Bob Pearson
  0 siblings, 2 replies; 3+ messages in thread
From: Bob Pearson @ 2020-11-06 23:03 UTC (permalink / raw)
  To: jgg, zyjzyj2000, linux-rdma; +Cc: Bob Pearson

This patch series supports a matching user space patch set:

	Provider/rxe: Implement extended verbs APIs

Together these implement the following erxtended verbs APIs:
        ibv_query_device_ex
        ibv_create_cq_ex
        ibv_create_qp_ex

They also implement the field parse and set ops in struct ibv_cq and ibv_qp.

Introduce a pair of SW capability bit masks that are exchanged between
the user space provider and the kernel space driver during the
ibv_alloc_context verb to allow the provider and driver to adjust
shared data structures depending on which capabilities are supported.
This is an extensible mechanism to avoid changes to ABI version.

Bob Pearson (2):
  RDMA/rxe: Exchange capabilities with provider
  RDMA/rxe: implement create_cq_ex verb

 drivers/infiniband/sw/rxe/rxe.c       |  2 ++
 drivers/infiniband/sw/rxe/rxe.h       |  2 ++
 drivers/infiniband/sw/rxe/rxe_comp.c  |  9 +++++-
 drivers/infiniband/sw/rxe/rxe_cq.c    | 19 +++++++----
 drivers/infiniband/sw/rxe/rxe_resp.c  | 20 ++++++++----
 drivers/infiniband/sw/rxe/rxe_verbs.c | 46 ++++++++++++++++++++++++---
 drivers/infiniband/sw/rxe/rxe_verbs.h | 15 ++++++---
 include/uapi/rdma/rdma_user_rxe.h     | 43 +++++++++++++++++++++++++
 8 files changed, 132 insertions(+), 24 deletions(-)

Signed-off-by: Bob Pearson <rpearson@hpe.com>
-- 
2.27.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] RDMA/rxe: Exchange capabilities with provider
  2020-11-06 23:03 [PATCH 0/2] RDMA/rxe: Implement extended verbs APIs Bob Pearson
@ 2020-11-06 23:03 ` Bob Pearson
  2020-11-06 23:03 ` [PATCH 2/2] RDMA/rxe: Implement the create_cq_ex verb Bob Pearson
  1 sibling, 0 replies; 3+ messages in thread
From: Bob Pearson @ 2020-11-06 23:03 UTC (permalink / raw)
  To: jgg, zyjzyj2000, linux-rdma; +Cc: Bob Pearson

Exchange provider and driver capabilities during
alloc_ucontext verb. Default is none. Will allow
more flexibility in ABI extensions without breaking
compatibility.

Signed-off-by: Bob Pearson <rpearson@hpe.com>
---
 drivers/infiniband/sw/rxe/rxe.c       |  2 ++
 drivers/infiniband/sw/rxe/rxe_verbs.c | 23 +++++++++++++++++++++++
 drivers/infiniband/sw/rxe/rxe_verbs.h |  3 +++
 include/uapi/rdma/rdma_user_rxe.h     | 12 ++++++++++++
 4 files changed, 40 insertions(+)

diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c
index 95f0de0c8b49..dbd84347e7df 100644
--- a/drivers/infiniband/sw/rxe/rxe.c
+++ b/drivers/infiniband/sw/rxe/rxe.c
@@ -73,6 +73,8 @@ static void rxe_init_device_param(struct rxe_dev *rxe)
 			rxe->ndev->dev_addr);
 
 	rxe->max_ucontext			= RXE_MAX_UCONTEXT;
+
+	rxe->driver_cap				= RXE_CAP_NONE;
 }
 
 /* initialize port attributes */
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 8af2bb968f6d..070f050b9793 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -110,6 +110,29 @@ static int rxe_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
 {
 	struct rxe_dev *rxe = to_rdev(uctx->device);
 	struct rxe_ucontext *uc = to_ruc(uctx);
+	struct rxe_alloc_context_cmd cmd = {};
+	struct rxe_alloc_context_resp __user *resp = NULL;
+	int err;
+
+	if (udata) {
+		if (udata->inlen >= sizeof(cmd)) {
+			err = ib_copy_from_udata(&cmd, udata, sizeof(cmd));
+			if (err)
+				return err;
+		}
+
+		if (udata->outlen >= sizeof(resp))
+			resp = udata->outbuf;
+	}
+
+	uc->provider_cap = cmd.provider_cap;
+
+	if (resp) {
+		err = copy_to_user(&resp->driver_cap, &rxe->driver_cap,
+				   sizeof(resp->driver_cap));
+		if (err)
+			return err;
+	}
 
 	return rxe_add_to_pool(&rxe->uc_pool, &uc->pelem);
 }
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
index 57967fc39c04..bc021f15ef06 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
@@ -36,6 +36,7 @@ static inline int psn_compare(u32 psn_a, u32 psn_b)
 struct rxe_ucontext {
 	struct ib_ucontext ibuc;
 	struct rxe_pool_entry	pelem;
+	u64			provider_cap;
 };
 
 struct rxe_pd {
@@ -358,6 +359,8 @@ struct rxe_dev {
 
 	struct net_device	*ndev;
 
+	u64			driver_cap;
+
 	int			xmit_errors;
 
 	struct rxe_pool		uc_pool;
diff --git a/include/uapi/rdma/rdma_user_rxe.h b/include/uapi/rdma/rdma_user_rxe.h
index e591d8c1f3cf..70ac031e0a88 100644
--- a/include/uapi/rdma/rdma_user_rxe.h
+++ b/include/uapi/rdma/rdma_user_rxe.h
@@ -158,6 +158,18 @@ struct rxe_recv_wqe {
 	struct rxe_dma_info	dma;
 };
 
+enum rxe_capabilities {
+	RXE_CAP_NONE		= 0,
+};
+
+struct rxe_alloc_context_cmd {
+	__aligned_u64		provider_cap;
+};
+
+struct rxe_alloc_context_resp {
+	__aligned_u64		driver_cap;
+};
+
 struct rxe_create_cq_resp {
 	struct mminfo mi;
 };
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] RDMA/rxe: Implement the create_cq_ex verb
  2020-11-06 23:03 [PATCH 0/2] RDMA/rxe: Implement extended verbs APIs Bob Pearson
  2020-11-06 23:03 ` [PATCH 1/2] RDMA/rxe: Exchange capabilities with provider Bob Pearson
@ 2020-11-06 23:03 ` Bob Pearson
  1 sibling, 0 replies; 3+ messages in thread
From: Bob Pearson @ 2020-11-06 23:03 UTC (permalink / raw)
  To: jgg, zyjzyj2000, linux-rdma; +Cc: Bob Pearson

Together with a matching commit from the rxe provider in user space
this patch implements the ibv_create_cq_ex extended verb.

Uses a RXE_CAP_CMD_EX driver capability bit to negotiate with the
provider whether to support the verb.

Adjusts the size of work completion struct in the completion queue
depending on whether the CQ belongs to the kernel or user space.
And, if user space whether the create_cq or create_cq_ex verbs was
used.

Signed-off-by: Bob Pearson <rpearson@hpe.com>
---
 drivers/infiniband/sw/rxe/rxe.c       |  2 +-
 drivers/infiniband/sw/rxe/rxe.h       |  2 ++
 drivers/infiniband/sw/rxe/rxe_comp.c  |  9 +++++++-
 drivers/infiniband/sw/rxe/rxe_cq.c    | 19 ++++++++++------
 drivers/infiniband/sw/rxe/rxe_resp.c  | 20 +++++++++++------
 drivers/infiniband/sw/rxe/rxe_verbs.c | 23 ++++++++++++++++----
 drivers/infiniband/sw/rxe/rxe_verbs.h | 12 ++++++-----
 include/uapi/rdma/rdma_user_rxe.h     | 31 +++++++++++++++++++++++++++
 8 files changed, 93 insertions(+), 25 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c
index dbd84347e7df..361e7380c75b 100644
--- a/drivers/infiniband/sw/rxe/rxe.c
+++ b/drivers/infiniband/sw/rxe/rxe.c
@@ -74,7 +74,7 @@ static void rxe_init_device_param(struct rxe_dev *rxe)
 
 	rxe->max_ucontext			= RXE_MAX_UCONTEXT;
 
-	rxe->driver_cap				= RXE_CAP_NONE;
+	rxe->driver_cap				= RXE_CAP_CMD_EX;
 }
 
 /* initialize port attributes */
diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h
index 623fd17df02d..2ccc52c1a2a2 100644
--- a/drivers/infiniband/sw/rxe/rxe.h
+++ b/drivers/infiniband/sw/rxe/rxe.h
@@ -18,6 +18,7 @@
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
+#include <rdma/rdma_user_rxe.h>
 #include <rdma/ib_pack.h>
 #include <rdma/ib_smi.h>
 #include <rdma/ib_umem.h>
@@ -32,6 +33,7 @@
 #include "rxe_verbs.h"
 #include "rxe_loc.h"
 
+
 /*
  * Version 1 and Version 2 are identical on 64 bit machines, but on 32 bit
  * machines Version 2 has a different struct layout.
diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
index 0a1e6393250b..2c5bede91373 100644
--- a/drivers/infiniband/sw/rxe/rxe_comp.c
+++ b/drivers/infiniband/sw/rxe/rxe_comp.c
@@ -389,7 +389,7 @@ static void make_send_cqe(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
 		wc->byte_len		= wqe->dma.length;
 		wc->qp			= &qp->ibqp;
 	} else {
-		struct ib_uverbs_wc	*uwc	= &cqe->uibwc;
+		struct rxe_uverbs_wc	*uwc	= &cqe->ruwc;
 
 		uwc->wr_id		= wqe->wr.wr_id;
 		uwc->status		= wqe->status;
@@ -399,6 +399,13 @@ static void make_send_cqe(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
 			uwc->wc_flags = IB_WC_WITH_IMM;
 		uwc->byte_len		= wqe->dma.length;
 		uwc->qp_num		= qp->ibqp.qp_num;
+
+		/* flags only for cq_ex */
+		if (qp->scq->flags &
+		    IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
+			uwc->timestamp	= (u64)ktime_get();
+			uwc->realtime	= (u64)ktime_get_real();
+		}
 	}
 }
 
diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c
index 43394c3f29d4..0ca7bede8d29 100644
--- a/drivers/infiniband/sw/rxe/rxe_cq.c
+++ b/drivers/infiniband/sw/rxe/rxe_cq.c
@@ -59,9 +59,17 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
 		     struct rxe_create_cq_resp __user *uresp)
 {
 	int err;
+	size_t wc_size;
 
-	cq->queue = rxe_queue_init(rxe, &cqe,
-				   sizeof(struct rxe_cqe));
+	if (cq->is_user)
+		wc_size = (cq->is_ex) ? sizeof(struct rxe_uverbs_wc)
+				      : sizeof(struct ib_uverbs_wc);
+	else
+		wc_size = sizeof(struct ib_wc);
+
+	cq->wc_size = wc_size;
+
+	cq->queue = rxe_queue_init(rxe, &cqe, wc_size);
 	if (!cq->queue) {
 		pr_warn("unable to create cq\n");
 		return -ENOMEM;
@@ -75,9 +83,6 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
 		return err;
 	}
 
-	if (uresp)
-		cq->is_user = 1;
-
 	cq->is_dying = false;
 
 	tasklet_setup(&cq->comp_task, rxe_send_complete);
@@ -94,7 +99,7 @@ int rxe_cq_resize_queue(struct rxe_cq *cq, int cqe,
 	int err;
 
 	err = rxe_queue_resize(cq->queue, (unsigned int *)&cqe,
-			       sizeof(struct rxe_cqe), udata,
+			       cq->wc_size, udata,
 			       uresp ? &uresp->mi : NULL, NULL, &cq->cq_lock);
 	if (!err)
 		cq->ibcq.cqe = cqe;
@@ -121,7 +126,7 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
 		return -EBUSY;
 	}
 
-	memcpy(producer_addr(cq->queue), cqe, sizeof(*cqe));
+	memcpy(producer_addr(cq->queue), cqe, cq->wc_size);
 
 	/* make sure all changes to the CQ are written before we update the
 	 * producer pointer
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index c7e3b6a4af38..ab564c4db2d6 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -812,7 +812,7 @@ static enum resp_states do_complete(struct rxe_qp *qp,
 {
 	struct rxe_cqe cqe;
 	struct ib_wc *wc = &cqe.ibwc;
-	struct ib_uverbs_wc *uwc = &cqe.uibwc;
+	struct rxe_uverbs_wc *uwc = &cqe.ruwc;
 	struct rxe_recv_wqe *wqe = qp->resp.wqe;
 	struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
 
@@ -822,13 +822,13 @@ static enum resp_states do_complete(struct rxe_qp *qp,
 	memset(&cqe, 0, sizeof(cqe));
 
 	if (qp->rcq->is_user) {
-		uwc->status             = qp->resp.status;
-		uwc->qp_num             = qp->ibqp.qp_num;
-		uwc->wr_id              = wqe->wr_id;
+		uwc->status		= qp->resp.status;
+		uwc->qp_num		= qp->ibqp.qp_num;
+		uwc->wr_id		= wqe->wr_id;
 	} else {
-		wc->status              = qp->resp.status;
-		wc->qp                  = &qp->ibqp;
-		wc->wr_id               = wqe->wr_id;
+		wc->status		= qp->resp.status;
+		wc->qp			= &qp->ibqp;
+		wc->wr_id		= wqe->wr_id;
 	}
 
 	if (wc->status == IB_WC_SUCCESS) {
@@ -863,6 +863,12 @@ static enum resp_states do_complete(struct rxe_qp *qp,
 				uwc->src_qp = deth_sqp(pkt);
 
 			uwc->port_num		= qp->attr.port_num;
+
+			if (qp->rcq->flags &
+			    IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
+				uwc->timestamp	= (u64)ktime_get();
+				uwc->realtime	= (u64)ktime_get_real();
+			}
 		} else {
 			struct sk_buff *skb = PKT_TO_SKB(pkt);
 
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 070f050b9793..1b1f451ce786 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -781,28 +781,43 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
 	return err;
 }
 
-static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+static int rxe_create_cq(struct ib_cq *ibcq,
+			 const struct ib_cq_init_attr *attr,
 			 struct ib_udata *udata)
 {
 	int err;
 	struct ib_device *dev = ibcq->device;
 	struct rxe_dev *rxe = to_rdev(dev);
 	struct rxe_cq *cq = to_rcq(ibcq);
+	struct rxe_create_cq_cmd cmd = {};
 	struct rxe_create_cq_resp __user *uresp = NULL;
 
 	if (udata) {
+		cq->is_user = 1;
+
 		if (udata->outlen < sizeof(*uresp))
 			return -EINVAL;
 		uresp = udata->outbuf;
-	}
 
-	if (attr->flags)
-		return -EOPNOTSUPP;
+		if (udata->inlen) {
+			if (udata->inlen < sizeof(cmd))
+				return -EINVAL;
+			err = ib_copy_from_udata(&cmd, udata, sizeof(cmd));
+			if (err)
+				return err;
+
+			cq->is_ex = cmd.is_ex;
+		} else {
+			cq->is_ex = 0;
+		}
+	}
 
 	err = rxe_cq_chk_attr(rxe, NULL, attr->cqe, attr->comp_vector);
 	if (err)
 		return err;
 
+	cq->flags = attr->flags;
+
 	err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, udata,
 			       uresp);
 	if (err)
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
index bc021f15ef06..618ee188ad9e 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
@@ -9,7 +9,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
-#include <rdma/rdma_user_rxe.h>
 #include "rxe_pool.h"
 #include "rxe_task.h"
 #include "rxe_hw_counters.h"
@@ -54,7 +53,7 @@ struct rxe_ah {
 struct rxe_cqe {
 	union {
 		struct ib_wc		ibwc;
-		struct ib_uverbs_wc	uibwc;
+		struct rxe_uverbs_wc	ruwc;
 	};
 };
 
@@ -62,11 +61,14 @@ struct rxe_cq {
 	struct ib_cq		ibcq;
 	struct rxe_pool_entry	pelem;
 	struct rxe_queue	*queue;
+	struct tasklet_struct	comp_task;
 	spinlock_t		cq_lock;
-	u8			notify;
-	bool			is_dying;
+	size_t			wc_size;
+	u32			flags;
 	int			is_user;
-	struct tasklet_struct	comp_task;
+	int			is_ex;
+	bool			is_dying;
+	u8			notify;
 };
 
 enum wqe_state {
diff --git a/include/uapi/rdma/rdma_user_rxe.h b/include/uapi/rdma/rdma_user_rxe.h
index 70ac031e0a88..e8bde1b6d08e 100644
--- a/include/uapi/rdma/rdma_user_rxe.h
+++ b/include/uapi/rdma/rdma_user_rxe.h
@@ -158,8 +158,35 @@ struct rxe_recv_wqe {
 	struct rxe_dma_info	dma;
 };
 
+struct rxe_uverbs_wc {
+	/* keep these the same as ib_uverbs_wc */
+	__aligned_u64		wr_id;
+	__u32			status;
+	__u32			opcode;
+	__u32			vendor_err;
+	__u32			byte_len;
+	union {
+		__be32		imm_data;
+		__u32		invalidate_rkey;
+	} ex;
+	__u32			qp_num;
+	__u32			src_qp;
+	__u32			wc_flags;
+	__u16			pkey_index;
+	__u16			slid;
+	__u8			sl;
+	__u8			dlid_path_bits;
+	__u8			port_num;
+	__u8			reserved;
+
+	/* any extras go here */
+	__aligned_u64		timestamp;
+	__aligned_u64		realtime;
+};
+
 enum rxe_capabilities {
 	RXE_CAP_NONE		= 0,
+	RXE_CAP_CMD_EX		= 1ULL << 0,
 };
 
 struct rxe_alloc_context_cmd {
@@ -170,6 +197,10 @@ struct rxe_alloc_context_resp {
 	__aligned_u64		driver_cap;
 };
 
+struct rxe_create_cq_cmd {
+	__aligned_u64 is_ex;
+};
+
 struct rxe_create_cq_resp {
 	struct mminfo mi;
 };
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-11-06 23:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-06 23:03 [PATCH 0/2] RDMA/rxe: Implement extended verbs APIs Bob Pearson
2020-11-06 23:03 ` [PATCH 1/2] RDMA/rxe: Exchange capabilities with provider Bob Pearson
2020-11-06 23:03 ` [PATCH 2/2] RDMA/rxe: Implement the create_cq_ex verb Bob Pearson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.