1167465SmpThis patch includes the following commits from OFED 1.3 libibverbs:
259243SobrienImplement eXtended Reliable Connections (a7df4af8eb84738f36db4161a4272fa02fc6741e)
359243SobrienRe-define IBV_DEVICE_XRC to conform to its new position (5042a9cab0ae2f7ad61bdf88dfed6fb10b700797)
459243SobrienSet "is_srq" flag only when the QP has an SRQ (6f6d29e74ca0c19a8821990aad603e3c575b7f4d)
559243Sobrienfor XRC QPs, return xrc_domain in ibv_query_qp (018c44a44ff0344dfe7cf5f6598f81d81769164e)
659243Sobrien
759243SobrienV2:
859243Sobrien1. checkpatch.pl cleanups
959243Sobrien2. fixed u64 alignment problems in uverbs.h ABI structs
1059243Sobrien3. eliminated unnecessary default_symvers
114. modified xrc_ops to more_ops
12
13Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
14 include/infiniband/driver.h   |   11 +++++
15 include/infiniband/kern-abi.h |   47 ++++++++++++++++++++++-
16 include/infiniband/verbs.h    |   85 ++++++++++++++++++++++++++++++++++++++++-
17 src/cmd.c                     |   72 ++++++++++++++++++++++++++++++++++-
18 src/libibverbs.map            |    6 +++
19 src/verbs.c                   |   54 ++++++++++++++++++++++++++
20 6 files changed, 271 insertions(+), 4 deletions(-)
21
22Index: libibverbs/include/infiniband/driver.h
23===================================================================
24--- libibverbs.orig/include/infiniband/driver.h	2009-11-01 15:18:17.920111000 +0200
25+++ libibverbs/include/infiniband/driver.h	2009-11-01 15:18:20.624171000 +0200
26@@ -99,6 +99,11 @@ int ibv_cmd_create_srq(struct ibv_pd *pd
27 		       struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
28 		       struct ibv_create_srq *cmd, size_t cmd_size,
29 		       struct ibv_create_srq_resp *resp, size_t resp_size);
30+int ibv_cmd_create_xrc_srq(struct ibv_pd *pd,
31+		       struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
32+		       uint32_t xrc_domain, uint32_t xrc_cq,
33+		       struct ibv_create_xrc_srq *cmd, size_t cmd_size,
34+		       struct ibv_create_srq_resp *resp, size_t resp_size);
35 int ibv_cmd_modify_srq(struct ibv_srq *srq,
36 		       struct ibv_srq_attr *srq_attr,
37 		       int srq_attr_mask,
38@@ -134,6 +139,12 @@ int ibv_cmd_detach_mcast(struct ibv_qp *
39 
40 int ibv_dontfork_range(void *base, size_t size);
41 int ibv_dofork_range(void *base, size_t size);
42+int ibv_cmd_open_xrc_domain(struct ibv_context *context, int fd, int oflag,
43+			    struct ibv_xrc_domain *d,
44+			    struct ibv_open_xrc_domain_resp *resp,
45+			    size_t resp_size);
46+int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d);
47+
48 
49 /*
50  * sysfs helper functions
51Index: libibverbs/include/infiniband/kern-abi.h
52===================================================================
53--- libibverbs.orig/include/infiniband/kern-abi.h	2009-11-01 15:18:17.921121000 +0200
54+++ libibverbs/include/infiniband/kern-abi.h	2009-11-01 15:18:20.629168000 +0200
55@@ -85,7 +85,10 @@ enum {
56 	IB_USER_VERBS_CMD_MODIFY_SRQ,
57 	IB_USER_VERBS_CMD_QUERY_SRQ,
58 	IB_USER_VERBS_CMD_DESTROY_SRQ,
59-	IB_USER_VERBS_CMD_POST_SRQ_RECV
60+	IB_USER_VERBS_CMD_POST_SRQ_RECV,
61+	IB_USER_VERBS_CMD_CREATE_XRC_SRQ,
62+	IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN,
63+	IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN
64 };
65 
66 /*
67@@ -706,6 +709,21 @@ struct ibv_create_srq {
68 	__u64 driver_data[0];
69 };
70 
71+struct ibv_create_xrc_srq {
72+	__u32 command;
73+	__u16 in_words;
74+	__u16 out_words;
75+	__u64 response;
76+	__u64 user_handle;
77+	__u32 pd_handle;
78+	__u32 max_wr;
79+	__u32 max_sge;
80+	__u32 srq_limit;
81+	__u32 xrcd_handle;
82+	__u32 xrc_cq;
83+	__u64 driver_data[0];
84+};
85+
86 struct ibv_create_srq_resp {
87 	__u32 srq_handle;
88 	__u32 max_wr;
89@@ -754,6 +772,30 @@ struct ibv_destroy_srq_resp {
90 	__u32 events_reported;
91 };
92 
93+struct ibv_open_xrc_domain {
94+	__u32 command;
95+	__u16 in_words;
96+	__u16 out_words;
97+	__u64 response;
98+	__u32 fd;
99+	__u32 oflags;
100+	__u64 driver_data[0];
101+};
102+
103+struct ibv_open_xrc_domain_resp {
104+	__u32 xrcd_handle;
105+};
106+
107+struct ibv_close_xrc_domain {
108+	__u32 command;
109+	__u16 in_words;
110+	__u16 out_words;
111+	__u64 response;
112+	__u32 xrcd_handle;
113+	__u32 reserved;
114+	__u64 driver_data[0];
115+};
116+
117 /*
118  * Compatibility with older ABI versions
119  */
120@@ -803,6 +845,9 @@ enum {
121 	 * trick opcodes in IBV_INIT_CMD() doesn't break.
122 	 */
123 	IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL_V2 = -1,
124+	IB_USER_VERBS_CMD_CREATE_XRC_SRQ_V2 = -1,
125+	IB_USER_VERBS_CMD_OPEN_XRC_DOMAIN_V2 = -1,
126+	IB_USER_VERBS_CMD_CLOSE_XRC_DOMAIN_V2 = -1,
127 };
128 
129 struct ibv_destroy_cq_v1 {
130Index: libibverbs/include/infiniband/verbs.h
131===================================================================
132--- libibverbs.orig/include/infiniband/verbs.h	2009-11-01 15:18:17.924118000 +0200
133+++ libibverbs/include/infiniband/verbs.h	2009-11-01 15:18:20.635171000 +0200
134@@ -92,7 +92,8 @@ enum ibv_device_cap_flags {
135 	IBV_DEVICE_SYS_IMAGE_GUID	= 1 << 11,
136 	IBV_DEVICE_RC_RNR_NAK_GEN	= 1 << 12,
137 	IBV_DEVICE_SRQ_RESIZE		= 1 << 13,
138-	IBV_DEVICE_N_NOTIFY_CQ		= 1 << 14
139+	IBV_DEVICE_N_NOTIFY_CQ		= 1 << 14,
140+	IBV_DEVICE_XRC		        = 1 << 20
141 };
142 
143 enum ibv_atomic_cap {
144@@ -371,6 +372,11 @@ struct ibv_ah_attr {
145 	uint8_t			port_num;
146 };
147 
148+struct ibv_xrc_domain {
149+	struct ibv_context     *context;
150+	uint32_t		handle;
151+};
152+
153 enum ibv_srq_attr_mask {
154 	IBV_SRQ_MAX_WR	= 1 << 0,
155 	IBV_SRQ_LIMIT	= 1 << 1
156@@ -390,7 +396,8 @@ struct ibv_srq_init_attr {
157 enum ibv_qp_type {
158 	IBV_QPT_RC = 2,
159 	IBV_QPT_UC,
160-	IBV_QPT_UD
161+	IBV_QPT_UD,
162+	IBV_QPT_XRC
163 };
164 
165 struct ibv_qp_cap {
166@@ -409,6 +416,7 @@ struct ibv_qp_init_attr {
167 	struct ibv_qp_cap	cap;
168 	enum ibv_qp_type	qp_type;
169 	int			sq_sig_all;
170+	struct ibv_xrc_domain  *xrc_domain;
171 };
172 
173 enum ibv_qp_attr_mask {
174@@ -527,6 +535,7 @@ struct ibv_send_wr {
175 			uint32_t	remote_qkey;
176 		} ud;
177 	} wr;
178+	uint32_t		xrc_remote_srq_num;
179 };
180 
181 struct ibv_recv_wr {
182@@ -554,6 +563,10 @@ struct ibv_srq {
183 	pthread_mutex_t		mutex;
184 	pthread_cond_t		cond;
185 	uint32_t		events_completed;
186+
187+	uint32_t		xrc_srq_num;
188+	struct ibv_xrc_domain  *xrc_domain;
189+	struct ibv_cq	       *xrc_cq;
190 };
191 
192 struct ibv_qp {
193@@ -571,6 +584,8 @@ struct ibv_qp {
194 	pthread_mutex_t		mutex;
195 	pthread_cond_t		cond;
196 	uint32_t		events_completed;
197+
198+	struct ibv_xrc_domain  *xrc_domain;
199 };
200 
201 struct ibv_comp_channel {
202@@ -625,6 +640,16 @@ struct ibv_device {
203 	char			ibdev_path[IBV_SYSFS_PATH_MAX];
204 };
205 
206+struct ibv_more_ops {
207+	struct ibv_srq *	(*create_xrc_srq)(struct ibv_pd *pd,
208+						  struct ibv_xrc_domain *xrc_domain,
209+						  struct ibv_cq *xrc_cq,
210+						  struct ibv_srq_init_attr *srq_init_attr);
211+	struct ibv_xrc_domain *	(*open_xrc_domain)(struct ibv_context *context,
212+						   int fd, int oflag);
213+	int			(*close_xrc_domain)(struct ibv_xrc_domain *d);
214+};
215+
216 struct ibv_context_ops {
217 	int			(*query_device)(struct ibv_context *context,
218 					      struct ibv_device_attr *device_attr);
219@@ -691,6 +716,7 @@ struct ibv_context {
220 	int			num_comp_vectors;
221 	pthread_mutex_t		mutex;
222 	void		       *abi_compat;
223+	struct ibv_more_ops     *more_ops;
224 };
225 
226 /**
227@@ -913,6 +939,25 @@ struct ibv_srq *ibv_create_srq(struct ib
228 			       struct ibv_srq_init_attr *srq_init_attr);
229 
230 /**
231+ * ibv_create_xrc_srq - Creates a SRQ associated with the specified protection
232+ *   domain and xrc domain.
233+ * @pd: The protection domain associated with the SRQ.
234+ * @xrc_domain: The XRC domain associated with the SRQ.
235+ * @xrc_cq: CQ to report completions for XRC packets on.
236+ *
237+ * @srq_init_attr: A list of initial attributes required to create the SRQ.
238+ *
239+ * srq_attr->max_wr and srq_attr->max_sge are read the determine the
240+ * requested size of the SRQ, and set to the actual values allocated
241+ * on return.  If ibv_create_srq() succeeds, then max_wr and max_sge
242+ * will always be at least as large as the requested values.
243+ */
244+struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd,
245+				   struct ibv_xrc_domain *xrc_domain,
246+				   struct ibv_cq *xrc_cq,
247+				   struct ibv_srq_init_attr *srq_init_attr);
248+
249+/**
250  * ibv_modify_srq - Modifies the attributes for the specified SRQ.
251  * @srq: The SRQ to modify.
252  * @srq_attr: On input, specifies the SRQ attributes to modify.  On output,
253@@ -1093,6 +1138,42 @@ const char *ibv_port_state_str(enum ibv_
254  */
255 const char *ibv_event_type_str(enum ibv_event_type event);
256 
257+/**
258+ * ibv_open_xrc_domain - open an XRC domain
259+ * Returns a reference to an XRC domain.
260+ *
261+ * @context: Device context
262+ * @fd: descriptor for inode associated with the domain
263+ *     If fd == -1, no inode is associated with the domain; in this ca= se,
264+ *     the only legal value for oflag is O_CREAT
265+ *
266+ * @oflag: oflag values are constructed by OR-ing flags from the following list
267+ *
268+ * O_CREAT
269+ *     If a domain belonging to device named by context is already associated
270+ *     with the inode, this flag has no effect, except as noted under O_EXCL
271+ *     below. Otherwise, a new XRC domain is created and is associated with
272+ *     inode specified by fd.
273+ *
274+ * O_EXCL
275+ *     If O_EXCL and O_CREAT are set, open will fail if a domain associated with
276+ *     the inode exists. The check for the existence of the domain and creation
277+ *     of the domain if it does not exist is atomic with respect to other
278+ *     processes executing open with fd naming the same inode.
279+ */
280+struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context,
281+					   int fd, int oflag);
282+
283+/**
284+ * ibv_close_xrc_domain - close an XRC domain
285+ * If this is the last reference, destroys the domain.
286+ *
287+ * @d: reference to XRC domain to close
288+ *
289+ * close is implicitly performed at process exit.
290+ */
291+int ibv_close_xrc_domain(struct ibv_xrc_domain *d);
292+
293 END_C_DECLS
294 
295 #  undef __attribute_const
296Index: libibverbs/src/cmd.c
297===================================================================
298--- libibverbs.orig/src/cmd.c	2009-11-01 15:18:17.927111000 +0200
299+++ libibverbs/src/cmd.c	2009-11-01 15:18:20.643167000 +0200
300@@ -483,6 +483,34 @@ int ibv_cmd_create_srq(struct ibv_pd *pd
301 	return 0;
302 }
303 
304+int ibv_cmd_create_xrc_srq(struct ibv_pd *pd,
305+		       struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
306+		       uint32_t xrcd_handle, uint32_t xrc_cq,
307+		       struct ibv_create_xrc_srq *cmd, size_t cmd_size,
308+		       struct ibv_create_srq_resp *resp, size_t resp_size)
309+{
310+	IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_XRC_SRQ, resp, resp_size);
311+	cmd->user_handle = (uintptr_t) srq;
312+	cmd->pd_handle 	 = pd->handle;
313+	cmd->max_wr      = attr->attr.max_wr;
314+	cmd->max_sge     = attr->attr.max_sge;
315+	cmd->srq_limit   = attr->attr.srq_limit;
316+	cmd->xrcd_handle = xrcd_handle;
317+	cmd->xrc_cq	 = xrc_cq;
318+
319+	if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
320+		return errno;
321+
322+	VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
323+
324+	srq->handle  = resp->srq_handle;
325+	srq->context = pd->context;
326+	attr->attr.max_wr = resp->max_wr;
327+	attr->attr.max_sge = resp->max_sge;
328+
329+	return 0;
330+}
331+
332 static int ibv_cmd_modify_srq_v3(struct ibv_srq *srq,
333 				 struct ibv_srq_attr *srq_attr,
334 				 int srq_attr_mask,
335@@ -603,7 +631,6 @@ int ibv_cmd_create_qp(struct ibv_pd *pd,
336 	cmd->pd_handle 	     = pd->handle;
337 	cmd->send_cq_handle  = attr->send_cq->handle;
338 	cmd->recv_cq_handle  = attr->recv_cq->handle;
339-	cmd->srq_handle      = attr->srq ? attr->srq->handle : 0;
340 	cmd->max_send_wr     = attr->cap.max_send_wr;
341 	cmd->max_recv_wr     = attr->cap.max_recv_wr;
342 	cmd->max_send_sge    = attr->cap.max_send_sge;
343@@ -612,6 +639,9 @@ int ibv_cmd_create_qp(struct ibv_pd *pd,
344 	cmd->sq_sig_all	     = attr->sq_sig_all;
345 	cmd->qp_type 	     = attr->qp_type;
346 	cmd->is_srq 	     = !!attr->srq;
347+	cmd->srq_handle      = attr->qp_type == IBV_QPT_XRC ?
348+		(attr->xrc_domain ? attr->xrc_domain->handle : 0) :
349+		(attr->srq ? attr->srq->handle : 0);
350 	cmd->reserved	     = 0;
351 
352 	if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
353@@ -722,6 +752,8 @@ int ibv_cmd_query_qp(struct ibv_qp *qp,
354 	init_attr->recv_cq                  = qp->recv_cq;
355 	init_attr->srq                      = qp->srq;
356 	init_attr->qp_type                  = qp->qp_type;
357+	if (qp->qp_type == IBV_QPT_XRC)
358+		init_attr->xrc_domain = qp->xrc_domain;
359 	init_attr->cap.max_send_wr          = resp.max_send_wr;
360 	init_attr->cap.max_recv_wr          = resp.max_recv_wr;
361 	init_attr->cap.max_send_sge         = resp.max_send_sge;
362@@ -1122,3 +1154,41 @@ int ibv_cmd_detach_mcast(struct ibv_qp *
363 
364 	return 0;
365 }
366+
367+int ibv_cmd_open_xrc_domain(struct ibv_context *context, int fd, int oflag,
368+			    struct ibv_xrc_domain *d,
369+			    struct ibv_open_xrc_domain_resp *resp,
370+			    size_t resp_size)
371+{
372+	struct ibv_open_xrc_domain cmd;
373+
374+	if (abi_ver < 6)
375+		return ENOSYS;
376+
377+	IBV_INIT_CMD_RESP(&cmd, sizeof cmd, OPEN_XRC_DOMAIN, resp, resp_size);
378+	cmd.fd = fd;
379+	cmd.oflags = oflag;
380+
381+	if (write(context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
382+		return errno;
383+
384+	d->handle = resp->xrcd_handle;
385+
386+	return 0;
387+}
388+
389+int ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d)
390+{
391+	struct ibv_close_xrc_domain cmd;
392+
393+	if (abi_ver < 6)
394+		return ENOSYS;
395+
396+	IBV_INIT_CMD(&cmd, sizeof cmd, CLOSE_XRC_DOMAIN);
397+	cmd.xrcd_handle = d->handle;
398+
399+	if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
400+		return errno;
401+	return 0;
402+}
403+
404Index: libibverbs/src/libibverbs.map
405===================================================================
406--- libibverbs.orig/src/libibverbs.map	2009-11-01 15:18:17.928115000 +0200
407+++ libibverbs/src/libibverbs.map	2009-11-01 15:18:20.646169000 +0200
408@@ -91,6 +91,12 @@ IBVERBS_1.1 {
409 		ibv_dontfork_range;
410 		ibv_dofork_range;
411 		ibv_register_driver;
412+		ibv_create_xrc_srq;
413+		ibv_cmd_create_xrc_srq;
414+		ibv_open_xrc_domain;
415+		ibv_cmd_open_xrc_domain;
416+		ibv_close_xrc_domain;
417+		ibv_cmd_close_xrc_domain;
418 
419 		ibv_node_type_str;
420 		ibv_port_state_str;
421Index: libibverbs/src/verbs.c
422===================================================================
423--- libibverbs.orig/src/verbs.c	2009-11-01 15:18:17.931119000 +0200
424+++ libibverbs/src/verbs.c	2009-11-01 15:18:20.650169000 +0200
425@@ -366,6 +366,9 @@ struct ibv_srq *__ibv_create_srq(struct
426 		srq->context          = pd->context;
427 		srq->srq_context      = srq_init_attr->srq_context;
428 		srq->pd               = pd;
429+		srq->xrc_domain       = NULL;
430+		srq->xrc_cq           = NULL;
431+		srq->xrc_srq_num      = 0;
432 		srq->events_completed = 0;
433 		pthread_mutex_init(&srq->mutex, NULL);
434 		pthread_cond_init(&srq->cond, NULL);
435@@ -375,6 +378,32 @@ struct ibv_srq *__ibv_create_srq(struct
436 }
437 default_symver(__ibv_create_srq, ibv_create_srq);
438 
439+struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd,
440+				   struct ibv_xrc_domain *xrc_domain,
441+				   struct ibv_cq *xrc_cq,
442+				   struct ibv_srq_init_attr *srq_init_attr)
443+{
444+	struct ibv_srq *srq;
445+
446+	if (!pd->context->more_ops)
447+		return NULL;
448+
449+	srq = pd->context->more_ops->create_xrc_srq(pd, xrc_domain,
450+						    xrc_cq, srq_init_attr);
451+	if (srq) {
452+		srq->context          = pd->context;
453+		srq->srq_context      = srq_init_attr->srq_context;
454+		srq->pd               = pd;
455+		srq->xrc_domain       = xrc_domain;
456+		srq->xrc_cq           = xrc_cq;
457+		srq->events_completed = 0;
458+		pthread_mutex_init(&srq->mutex, NULL);
459+		pthread_cond_init(&srq->cond, NULL);
460+	}
461+
462+	return srq;
463+}
464+
465 int __ibv_modify_srq(struct ibv_srq *srq,
466 		     struct ibv_srq_attr *srq_attr,
467 		     int srq_attr_mask)
468@@ -410,6 +439,8 @@ struct ibv_qp *__ibv_create_qp(struct ib
469 		qp->qp_type          = qp_init_attr->qp_type;
470 		qp->state	     = IBV_QPS_RESET;
471 		qp->events_completed = 0;
472+		qp->xrc_domain       = qp_init_attr->qp_type == IBV_QPT_XRC ?
473+			qp_init_attr->xrc_domain : NULL;
474 		pthread_mutex_init(&qp->mutex, NULL);
475 		pthread_cond_init(&qp->cond, NULL);
476 	}
477@@ -543,3 +574,26 @@ int __ibv_detach_mcast(struct ibv_qp *qp
478 	return qp->context->ops.detach_mcast(qp, gid, lid);
479 }
480 default_symver(__ibv_detach_mcast, ibv_detach_mcast);
481+
482+struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context,
483+					   int fd, int oflag)
484+{
485+	struct ibv_xrc_domain *d;
486+
487+	if (!context->more_ops)
488+		return NULL;
489+
490+	d = context->more_ops->open_xrc_domain(context, fd, oflag);
491+	if (d)
492+		d->context = context;
493+
494+	return d;
495+}
496+
497+int ibv_close_xrc_domain(struct ibv_xrc_domain *d)
498+{
499+	if (!d->context->more_ops)
500+		return 0;
501+
502+	return d->context->more_ops->close_xrc_domain(d);
503+}
504