|
1 #This patch was developed both in-house and from outside. We plan to submit it |
|
2 #upstream, but do not yet have a target date for doing so |
|
3 # |
|
4 # HG changeset patch |
|
5 # Parent f8684a1d3f02b9cc10a686daa8659805384ba51a |
|
6 25759055 OFUV (Userland) support for XRC APIs |
|
7 |
|
8 diff -r f8684a1d3f02 Makefile.am |
|
9 --- a/Makefile.am Mon Nov 21 11:48:20 2016 -0800 |
|
10 +++ b/Makefile.am Mon Mar 20 14:32:42 2017 -0700 |
|
11 @@ -45,7 +45,8 @@ |
|
12 |
|
13 libibverbsinclude_HEADERS = include/infiniband/arch.h include/infiniband/driver.h \ |
|
14 include/infiniband/kern-abi.h include/infiniband/opcode.h include/infiniband/verbs.h \ |
|
15 - include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h |
|
16 + include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h \ |
|
17 + include/infiniband/ofa_verbs.h |
|
18 |
|
19 man_MANS = man/ibv_asyncwatch.1 man/ibv_devices.1 man/ibv_devinfo.1 \ |
|
20 man/ibv_shpd_pingpong.1 \ |
|
21 @@ -64,7 +65,8 @@ |
|
22 man/ibv_query_srq.3 man/ibv_rate_to_mult.3 man/ibv_reg_mr.3 \ |
|
23 man/ibv_req_notify_cq.3 man/ibv_resize_cq.3 man/ibv_rate_to_mbps.3 \ |
|
24 man/ibv_create_qp_ex.3 man/ibv_create_srq_ex.3 man/ibv_open_xrcd.3 \ |
|
25 - man/ibv_get_srq_num.3 man/ibv_open_qp.3 |
|
26 + man/ibv_get_srq_num.3 man/ibv_open_qp.3 man/ibv_create_xsrq.3 \ |
|
27 + man/ibv_xsrq_pingpong.1 |
|
28 |
|
29 DEBIAN = debian/changelog debian/compat debian/control debian/copyright \ |
|
30 debian/ibverbs-utils.install debian/libibverbs1.install \ |
|
31 diff -r f8684a1d3f02 Makefile.in |
|
32 --- a/Makefile.in Mon Nov 21 11:48:20 2016 -0800 |
|
33 +++ b/Makefile.in Mon Mar 20 14:32:42 2017 -0700 |
|
34 @@ -476,7 +476,8 @@ |
|
35 libibverbsincludedir = $(includedir)/infiniband |
|
36 libibverbsinclude_HEADERS = include/infiniband/arch.h include/infiniband/driver.h \ |
|
37 include/infiniband/kern-abi.h include/infiniband/opcode.h include/infiniband/verbs.h \ |
|
38 - include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h include/infiniband/ofa_solaris.h |
|
39 + include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h \ |
|
40 + include/infiniband/ofa_solaris.h include/infiniband/ofa_verbs.h |
|
41 |
|
42 man_MANS = man/ibv_asyncwatch.1 man/ibv_devices.1 man/ibv_devinfo.1 \ |
|
43 man/ibv_shpd_pingpong.1 \ |
|
44 @@ -495,7 +496,8 @@ |
|
45 man/ibv_query_srq.3 man/ibv_rate_to_mult.3 man/ibv_reg_mr.3 \ |
|
46 man/ibv_req_notify_cq.3 man/ibv_resize_cq.3 man/ibv_rate_to_mbps.3 \ |
|
47 man/ibv_create_qp_ex.3 man/ibv_create_srq_ex.3 man/ibv_open_xrcd.3 \ |
|
48 - man/ibv_get_srq_num.3 man/ibv_open_qp.3 |
|
49 + man/ibv_get_srq_num.3 man/ibv_open_qp.3 man/ibv_create_xsrq.3 \ |
|
50 + man/ibv_xsrq_pingpong.1 |
|
51 |
|
52 DEBIAN = debian/changelog debian/compat debian/control debian/copyright \ |
|
53 debian/ibverbs-utils.install debian/libibverbs1.install \ |
|
54 diff -r f8684a1d3f02 include/infiniband/ofa_verbs.h |
|
55 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|
56 +++ b/include/infiniband/ofa_verbs.h Mon Mar 20 14:32:42 2017 -0700 |
|
57 @@ -0,0 +1,140 @@ |
|
58 +/* |
|
59 + * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. |
|
60 + * Copyright (c) 2004, 2011-2012 Intel Corporation. All rights reserved. |
|
61 + * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. |
|
62 + * Copyright (c) 2005 PathScale, Inc. All rights reserved. |
|
63 + * |
|
64 + * This software is available to you under a choice of one of two |
|
65 + * licenses. You may choose to be licensed under the terms of the GNU |
|
66 + * General Public License (GPL) Version 2, available from the file |
|
67 + * COPYING in the main directory of this source tree, or the |
|
68 + * OpenIB.org BSD license below: |
|
69 + * |
|
70 + * Redistribution and use in source and binary forms, with or |
|
71 + * without modification, are permitted provided that the following |
|
72 + * conditions are met: |
|
73 + * |
|
74 + * - Redistributions of source code must retain the above |
|
75 + * copyright notice, this list of conditions and the following |
|
76 + * disclaimer. |
|
77 + * |
|
78 + * - Redistributions in binary form must reproduce the above |
|
79 + * copyright notice, this list of conditions and the following |
|
80 + * disclaimer in the documentation and/or other materials |
|
81 + * provided with the distribution. |
|
82 + * |
|
83 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
84 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
85 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
86 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
|
87 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
88 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
89 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
90 + * SOFTWARE. |
|
91 + */ |
|
92 + |
|
93 +#ifndef INFINIBAND_OFA_VERBS_H |
|
94 +#define INFINIBAND_OFA_VERBS_H |
|
95 + |
|
96 +struct ibv_srq_init_attr; |
|
97 +struct ibv_cq; |
|
98 +struct ibv_pd; |
|
99 +struct ibv_qp_init_attr; |
|
100 +struct ibv_qp_attr; |
|
101 + |
|
102 + |
|
103 +#ifdef __GNUC__ |
|
104 +#define DEPRECATED __attribute__((deprecated)) |
|
105 +#else |
|
106 +#define DEPRECATED |
|
107 +#endif |
|
108 + |
|
109 +/* XRC compatability layer */ |
|
110 +#define LEGACY_XRC_SRQ_HANDLE 0xffffffff |
|
111 + |
|
112 +struct ibv_xrc_domain { |
|
113 + struct ibv_context *context; |
|
114 + uint32_t handle; |
|
115 +}; |
|
116 + |
|
117 +struct ibv_srq_legacy { |
|
118 + struct ibv_context *context; |
|
119 + void *srq_context; |
|
120 + struct ibv_pd *pd; |
|
121 + uint32_t handle; |
|
122 + |
|
123 + uint32_t events_completed; |
|
124 + |
|
125 + uint32_t xrc_srq_num_bin_compat; |
|
126 + struct ibv_xrc_domain *xrc_domain_bin_compat; |
|
127 + struct ibv_cq *xrc_cq_bin_compat; |
|
128 + |
|
129 + pthread_mutex_t mutex; |
|
130 + pthread_cond_t cond; |
|
131 + |
|
132 + void *ibv_srq; |
|
133 + /* |
|
134 + * Below fields are for legacy source compatibility. They reside |
|
135 + * on the same offset as of those fields in struct ibv_srq. |
|
136 + */ |
|
137 + uint32_t xrc_srq_num; |
|
138 + struct ibv_xrc_domain *xrc_domain; |
|
139 + struct ibv_cq *xrc_cq; |
|
140 +}; |
|
141 + |
|
142 +/** |
|
143 + * ibv_open_xrc_domain - open an XRC domain |
|
144 + * Returns a reference to an XRC domain. |
|
145 + * |
|
146 + * @context: Device context |
|
147 + * @fd: descriptor for inode associated with the domain |
|
148 + * If fd == -1, no inode is associated with the domain; in this ca= se, |
|
149 + * the only legal value for oflag is O_CREAT |
|
150 + * |
|
151 + * @oflag: oflag values are constructed by OR-ing flags from the following list |
|
152 + * |
|
153 + * O_CREAT |
|
154 + * If a domain belonging to device named by context is already associated |
|
155 + * with the inode, this flag has no effect, except as noted under O_EXCL |
|
156 + * below. Otherwise, a new XRC domain is created and is associated with |
|
157 + * inode specified by fd. |
|
158 + * |
|
159 + * O_EXCL |
|
160 + * If O_EXCL and O_CREAT are set, open will fail if a domain associated with |
|
161 + * the inode exists. The check for the existence of the domain and creation |
|
162 + * of the domain if it does not exist is atomic with respect to other |
|
163 + * processes executing open with fd naming the same inode. |
|
164 + */ |
|
165 +struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context, |
|
166 + int fd, int oflag) DEPRECATED; |
|
167 + |
|
168 +/** |
|
169 + * ibv_create_xrc_srq - Creates a SRQ associated with the specified protection |
|
170 + * domain and xrc domain. |
|
171 + * @pd: The protection domain associated with the SRQ. |
|
172 + * @xrc_domain: The XRC domain associated with the SRQ. |
|
173 + * @xrc_cq: CQ to report completions for XRC packets on. |
|
174 + * |
|
175 + * @srq_init_attr: A list of initial attributes required to create the SRQ. |
|
176 + * |
|
177 + * srq_attr->max_wr and srq_attr->max_sge are read the determine the |
|
178 + * requested size of the SRQ, and set to the actual values allocated |
|
179 + * on return. If ibv_create_srq() succeeds, then max_wr and max_sge |
|
180 + * will always be at least as large as the requested values. |
|
181 + */ |
|
182 +struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd, |
|
183 + struct ibv_xrc_domain *xrc_domain, |
|
184 + struct ibv_cq *xrc_cq, |
|
185 + struct ibv_srq_init_attr *srq_init_attr) DEPRECATED; |
|
186 + |
|
187 +/** |
|
188 + * ibv_close_xrc_domain - close an XRC domain |
|
189 + * If this is the last reference, destroys the domain. |
|
190 + * |
|
191 + * @d: reference to XRC domain to close |
|
192 + * |
|
193 + * close is implicitly performed at process exit. |
|
194 + */ |
|
195 +int ibv_close_xrc_domain(struct ibv_xrc_domain *d) DEPRECATED; |
|
196 + |
|
197 +#endif |
|
198 diff -r f8684a1d3f02 include/infiniband/verbs.h |
|
199 --- a/include/infiniband/verbs.h Mon Nov 21 11:48:20 2016 -0800 |
|
200 +++ b/include/infiniband/verbs.h Mon Mar 20 14:32:42 2017 -0700 |
|
201 @@ -42,6 +42,7 @@ |
|
202 #include <errno.h> |
|
203 #if defined(__SVR4) && defined(__sun) |
|
204 #include <infiniband/ofa_solaris.h> |
|
205 +#include <infiniband/ofa_verbs.h> |
|
206 #endif |
|
207 |
|
208 #ifdef __cplusplus |
|
209 @@ -252,6 +253,8 @@ |
|
210 struct ibv_srq *srq; |
|
211 int port_num; |
|
212 union ibv_gid gid; |
|
213 + /* For source compatibility with legacy API */ |
|
214 + uint32_t xrc_qp_num; |
|
215 } element; |
|
216 enum ibv_event_type event_type; |
|
217 }; |
|
218 @@ -507,6 +510,7 @@ |
|
219 IBV_QPT_RC = 2, |
|
220 IBV_QPT_UC, |
|
221 IBV_QPT_UD, |
|
222 + IBV_QPT_XRC, /* XRC legacy compatible type */ |
|
223 IBV_QPT_RAW_PACKET = 8, |
|
224 IBV_QPT_XRC_SEND = 9, |
|
225 IBV_QPT_XRC_RECV |
|
226 @@ -536,6 +540,8 @@ |
|
227 struct ibv_qp_cap cap; |
|
228 enum ibv_qp_type qp_type; |
|
229 int sq_sig_all; |
|
230 + /* Below is needed for legacy compatibility */ |
|
231 + struct ibv_xrc_domain *xrc_domain; |
|
232 }; |
|
233 |
|
234 enum ibv_qp_init_attr_mask { |
|
235 @@ -692,10 +698,14 @@ |
|
236 } ud; |
|
237 } wr; |
|
238 union { |
|
239 - struct { |
|
240 - uint32_t remote_srqn; |
|
241 - } xrc; |
|
242 - } qp_type; |
|
243 + union { |
|
244 + struct { |
|
245 + uint32_t remote_srqn; |
|
246 + } xrc; |
|
247 + } qp_type; |
|
248 + |
|
249 + uint32_t xrc_remote_srq_num; |
|
250 + }; |
|
251 }; |
|
252 |
|
253 struct ibv_recv_wr { |
|
254 @@ -723,6 +733,25 @@ |
|
255 pthread_mutex_t mutex; |
|
256 pthread_cond_t cond; |
|
257 uint32_t events_completed; |
|
258 + |
|
259 + /* |
|
260 + * Below is for source compatibility with legacy XRC APIs. |
|
261 + * Padding is based on ibv_srq_legacy. |
|
262 + */ |
|
263 + uint32_t xrc_srq_num_bin_compat_padding; |
|
264 + struct ibv_xrc_domain *xrc_domain_bin_compat_padding; |
|
265 + struct ibv_cq *xrc_cq_bin_compat_padding; |
|
266 + void *ibv_srq_padding; |
|
267 + |
|
268 + /* legacy fields */ |
|
269 + uint32_t xrc_srq_num; |
|
270 + struct ibv_xrc_domain *xrc_domain; |
|
271 + struct ibv_cq *xrc_cq; |
|
272 +}; |
|
273 + |
|
274 +/* XRC source compat layer */ |
|
275 +enum ibv_event_flags { |
|
276 + IBV_XRC_QP_EVENT_FLAG = 0x80000000, |
|
277 }; |
|
278 |
|
279 struct ibv_qp { |
|
280 @@ -996,6 +1025,8 @@ |
|
281 |
|
282 struct verbs_context { |
|
283 /* "grows up" - new fields go here */ |
|
284 + void * (*drv_get_legacy_xrc) (struct ibv_srq *ibv_srq); |
|
285 + void (*drv_set_legacy_xrc) (struct ibv_srq *ibv_srq, void *legacy_xrc); |
|
286 int (*drv_ibv_destroy_flow) (struct ibv_flow *flow); |
|
287 int (*lib_ibv_destroy_flow) (struct ibv_flow *flow); |
|
288 struct ibv_flow * (*drv_ibv_create_flow) (struct ibv_qp *qp, |
|
289 diff -r f8684a1d3f02 man/ibv_create_qp_ex.3 |
|
290 --- a/man/ibv_create_qp_ex.3 Mon Nov 21 11:48:20 2016 -0800 |
|
291 +++ b/man/ibv_create_qp_ex.3 Mon Mar 20 14:32:42 2017 -0700 |
|
292 @@ -28,7 +28,7 @@ |
|
293 struct ibv_cq *recv_cq; /* CQ to be associated with the Receive Queue (RQ) */ |
|
294 struct ibv_srq *srq; /* SRQ handle if QP is to be associated with an SRQ, otherwise NULL */ |
|
295 struct ibv_qp_cap cap; /* QP capabilities */ |
|
296 -enum ibv_qp_type qp_type; /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, IBV_QPT_UD or IBV_QPT_RAW_PACKET */ |
|
297 +enum ibv_qp_type qp_type; /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_XRC_SEND, IBV_QPT_XRC_RECV, IBV_QPT_UC, IBV_QPT_UD or IBV_QPT_RAW_PACKET */ |
|
298 int sq_sig_all; /* If set, each Work Request (WR) submitted to the SQ generates a completion entry */ |
|
299 uint32_t comp_mask; /* Identifies valid fields */ |
|
300 struct ibv_pd *pd; /* PD to be associated with the QP */ |
|
301 diff -r f8684a1d3f02 man/ibv_create_xsrq.3 |
|
302 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|
303 +++ b/man/ibv_create_xsrq.3 Mon Mar 20 14:32:42 2017 -0700 |
|
304 @@ -0,0 +1,87 @@ |
|
305 +.\" -*- nroff -*- |
|
306 +.\" |
|
307 +.TH IBV_CREATE_XSRQ 3 2011-06-17 libibverbs "Libibverbs Programmer's Manual" |
|
308 +.SH "NAME" |
|
309 +ibv_create_xsrq, ibv_destroy_srq \- create or destroy a shared receive queue (SRQ) |
|
310 +.SH "SYNOPSIS" |
|
311 +.nf |
|
312 +.B #include |
|
313 +.sp |
|
314 +.BI "struct ibv_srq *ibv_create_xsrq(struct ibv_pd " "*pd" ", struct " |
|
315 +.BI " ibv_srq_init_attr " "*srq_init_attr" |
|
316 +); |
|
317 +.sp |
|
318 +.BI "int ibv_destroy_srq(struct ibv_srq " "*srq" ); |
|
319 +.fi |
|
320 +.SH "DESCRIPTION" |
|
321 +.B ibv_create_xsrq() |
|
322 +creates a shared receive queue (SRQ) associated with the protection domain |
|
323 +.I pd\fR. |
|
324 +The argument |
|
325 +.I srq_init_attr |
|
326 +is an ibv_srq_init_attr struct, as defined in . |
|
327 +.PP |
|
328 +.nf |
|
329 +struct ibv_srq_init_attr { |
|
330 +.in +8 |
|
331 +void *srq_context; /* Associated context of the SRQ |
|
332 +*/ |
|
333 +struct ibv_srq_attr attr; /* SRQ attributes */ |
|
334 +enum ibv_srq_type srq_type; /* Specifies type of SRQ to create |
|
335 +*/ |
|
336 +union { |
|
337 +.in +8 |
|
338 +struct { |
|
339 +.in +8 |
|
340 +struct ibv_xrcd *xrcd; /* XRC domain associated with an XRC SRQ */ |
|
341 +struct ibv_cq *cq; /* completion queue for an XRC SRQ*/ |
|
342 +.in -8 |
|
343 +} xrc; /* Extended attributes for IBV_SRQT_XRC type SRQs */ |
|
344 +.in -8 |
|
345 +} ext; |
|
346 +.in -8 |
|
347 +}; |
|
348 +.sp |
|
349 +.nf |
|
350 +struct ibv_srq_attr { |
|
351 +.in +8 |
|
352 +uint32_t max_wr; /* Requested max number of |
|
353 +outstanding work requests (WRs) in the SRQ */ |
|
354 +uint32_t max_sge; /* Requested max number of scatter |
|
355 +elements per WR */ |
|
356 +uint32_t srq_limit; /* The limit value of the SRQ |
|
357 +(ignored for ibv_create_srq) */ |
|
358 +.in -8 |
|
359 +}; |
|
360 +.fi |
|
361 +.PP |
|
362 +The function |
|
363 +.B ibv_create_xsrq() |
|
364 +will update the |
|
365 +.I srq_init_attr |
|
366 +struct with the original values of the SRQ that was created; the |
|
367 +values of max_wr and max_sge will be greater than or equal to the |
|
368 +values requested. |
|
369 +.PP |
|
370 +.B ibv_destroy_srq() |
|
371 +destroys the SRQ |
|
372 +.I srq\fR. |
|
373 +.SH "RETURN VALUE" |
|
374 +.B ibv_create_xsrq() |
|
375 +returns a pointer to the created SRQ, or NULL if the request fails. |
|
376 +.PP |
|
377 +.B ibv_destroy_srq() |
|
378 +returns 0 on success, or the value of errno on failure (which indicates |
|
379 +the failure reason). |
|
380 +.SH "NOTES" |
|
381 +.B ibv_destroy_srq() |
|
382 +fails if any queue pair is still associated with this SRQ. |
|
383 +.SH "SEE ALSO" |
|
384 +.BR ibv_alloc_pd (3), |
|
385 +.BR ibv_create_cq (3), |
|
386 +.BR ibv_open_xrcd (3), |
|
387 +.BR ibv_modify_srq (3), |
|
388 +.BR ibv_query_srq (3) |
|
389 +.SH "AUTHORS" |
|
390 +.TP |
|
391 +Sean Hefty |
|
392 diff -r f8684a1d3f02 man/ibv_xsrq_pingpong.1 |
|
393 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|
394 +++ b/man/ibv_xsrq_pingpong.1 Mon Mar 20 14:32:42 2017 -0700 |
|
395 @@ -0,0 +1,71 @@ |
|
396 +.TH IBV_XSRQ_PINGPONG 1 "May 24, 2016" "libibverbs" "USER COMMANDS" |
|
397 + |
|
398 +.SH NAME |
|
399 +ibv_xsrq_pingpong \- simple InfiniBand shared receive queue test |
|
400 + |
|
401 +.SH SYNOPSIS |
|
402 +.B ibv_xsrq_pingpong |
|
403 +[\-p port] [\-d device] [\-i ib port] [\-s size] [\-m mtu] [\-c clients] |
|
404 +[\-n num_tests] [\-l sl] [\-e] \fBHOSTNAME\fR |
|
405 + |
|
406 +.B ibv_xsrq_pingpong |
|
407 +[\-p port] [\-d device] [\-i ib port] [\-s size] [\-m mtu] [\-c clients] |
|
408 +[\-n num_tests] [\-l sl] [\-e] |
|
409 + |
|
410 +.SH DESCRIPTION |
|
411 +.PP |
|
412 +Run a simple ping-pong test over InfiniBand via the extended reliable |
|
413 +connected (XRC) transport service, using a shared receive queue (SRQ). |
|
414 + |
|
415 +.SH OPTIONS |
|
416 + |
|
417 +.PP |
|
418 +.TP |
|
419 +\fB\-p\fR, \fB\-\-port\fR=\fIPORT\fR |
|
420 +use TCP port \fIPORT\fR for initial synchronization (default 18515) |
|
421 +.TP |
|
422 +\fB\-d\fR, \fB\-\-ib\-dev\fR=\fIDEVICE\fR |
|
423 +use IB device \fIDEVICE\fR (default first device found) |
|
424 +.TP |
|
425 +\fB\-i\fR, \fB\-\-ib\-port\fR=\fIPORT\fR |
|
426 +use IB port \fIPORT\fR (default port 1) |
|
427 +.TP |
|
428 +\fB\-s\fR, \fB\-\-size\fR=\fISIZE\fR |
|
429 +ping-pong messages of size \fISIZE\fR (default 4096) |
|
430 +.TP |
|
431 +\fB\-m\fR, \fB\-\-mtu\fR=\fIMTU\fR |
|
432 +use path mtu of size \fIMTU\fR (default 2048) |
|
433 +.TP |
|
434 +\fB\-c\fR, \fB\-\-clients\fR=\fICLIENTS\fR |
|
435 +number of clients \fICLIENTS\fR (on server only, default 1) |
|
436 +.TP |
|
437 +\fB\-n\fR, \fB\-\-num\-tests\fR=\fINUM_TESTS\fR |
|
438 +perform \fINUM_TESTS\fR tests per client (default 5) |
|
439 +.TP |
|
440 +\fB\-l\fR, \fB\-\-sl\fR=\fISL\fR |
|
441 +use \fISL\fR as the service level value (default 0) |
|
442 +.TP |
|
443 +\fB\-e\fR, \fB\-\-events\fR |
|
444 +sleep while waiting for work completion events (default is to poll for |
|
445 +completions) |
|
446 + |
|
447 +.SH SEE ALSO |
|
448 +.BR ibv_rc_pingpong (1), |
|
449 +.BR ibv_uc_pingpong (1), |
|
450 +.BR ibv_ud_pingpong (1) |
|
451 +.BR ibv_srq_pingpong (1) |
|
452 + |
|
453 +.SH AUTHORS |
|
454 +.TP |
|
455 +Roland Dreier |
|
456 +.RI < [email protected] > |
|
457 +.TP |
|
458 +Jarod Wilson |
|
459 +.RI < [email protected] > |
|
460 + |
|
461 +.SH BUGS |
|
462 +The network synchronization between client and server instances is |
|
463 +weak, and does not prevent incompatible options from being used on the |
|
464 +two instances. The method used for retrieving work completions is not |
|
465 +strictly correct, and race conditions may cause failures on some |
|
466 +systems. |
|
467 diff -r f8684a1d3f02 src/cmd.c |
|
468 --- a/src/cmd.c Mon Nov 21 11:48:20 2016 -0800 |
|
469 +++ b/src/cmd.c Mon Mar 20 14:32:42 2017 -0700 |
|
470 @@ -815,6 +815,7 @@ |
|
471 cmd->user_handle = (uintptr_t) qp; |
|
472 |
|
473 if (attr_ex->comp_mask & IBV_QP_INIT_ATTR_XRCD) { |
|
474 + /* XRC receive side */ |
|
475 vxrcd = container_of(attr_ex->xrcd, struct verbs_xrcd, xrcd); |
|
476 cmd->pd_handle = vxrcd->handle; |
|
477 } else { |
|
478 @@ -824,7 +825,9 @@ |
|
479 cmd->pd_handle = attr_ex->pd->handle; |
|
480 cmd->send_cq_handle = attr_ex->send_cq->handle; |
|
481 |
|
482 - if (attr_ex->qp_type != IBV_QPT_XRC_SEND) { |
|
483 + /* XRC sender doesn't have a receive cq */ |
|
484 + if (attr_ex->qp_type != IBV_QPT_XRC_SEND && |
|
485 + attr_ex->qp_type != IBV_QPT_XRC) { |
|
486 cmd->recv_cq_handle = attr_ex->recv_cq->handle; |
|
487 cmd->srq_handle = attr_ex->srq ? attr_ex->srq->handle : 0; |
|
488 } |
|
489 @@ -847,7 +850,8 @@ |
|
490 #else |
|
491 cmd->sq_sig_all = attr_ex->sq_sig_all; |
|
492 #endif |
|
493 - cmd->qp_type = attr_ex->qp_type; |
|
494 + cmd->qp_type = (attr_ex->qp_type == IBV_QPT_XRC) ? |
|
495 + IBV_QPT_XRC_SEND : attr_ex->qp_type; |
|
496 cmd->is_srq = !!attr_ex->srq; |
|
497 cmd->reserved = 0; |
|
498 |
|
499 @@ -1215,6 +1219,9 @@ |
|
500 tmp->wr.ud.remote_qpn = i->wr.ud.remote_qpn; |
|
501 tmp->wr.ud.remote_qkey = i->wr.ud.remote_qkey; |
|
502 } else { |
|
503 + if (ibqp->qp_type == IBV_QPT_XRC_SEND) |
|
504 + tmp->qp_type.xrc.remote_srqn = |
|
505 + i->qp_type.xrc.remote_srqn; |
|
506 switch (i->opcode) { |
|
507 case IBV_WR_RDMA_WRITE: |
|
508 case IBV_WR_RDMA_WRITE_WITH_IMM: |
|
509 diff -r f8684a1d3f02 src/device.c |
|
510 --- a/src/device.c Mon Nov 21 11:48:20 2016 -0800 |
|
511 +++ b/src/device.c Mon Mar 20 14:32:42 2017 -0700 |
|
512 @@ -261,6 +261,9 @@ |
|
513 struct ibv_async_event *event) |
|
514 { |
|
515 struct ibv_kern_async_event ev; |
|
516 + struct verbs_context *vctx; |
|
517 + struct ibv_srq_legacy *ibv_srq_legacy = NULL; |
|
518 + struct ibv_qp *qp; |
|
519 |
|
520 if (read(context->async_fd, &ev, sizeof ev) != sizeof ev) |
|
521 return -1; |
|
522 @@ -281,11 +284,24 @@ |
|
523 case IBV_EVENT_PATH_MIG_ERR: |
|
524 case IBV_EVENT_QP_LAST_WQE_REACHED: |
|
525 event->element.qp = (void *) (uintptr_t) ev.element; |
|
526 + qp = ibv_find_xrc_qp(event->element.qp->qp_num); |
|
527 + if (qp) { |
|
528 + /* This is an XRC receive QP created by the legacy API */ |
|
529 + event->event_type |= IBV_XRC_QP_EVENT_FLAG; |
|
530 + event->element.qp = NULL; |
|
531 + event->element.xrc_qp_num = qp->qp_num; |
|
532 + } |
|
533 break; |
|
534 |
|
535 case IBV_EVENT_SRQ_ERR: |
|
536 case IBV_EVENT_SRQ_LIMIT_REACHED: |
|
537 - event->element.srq = (void *) (uintptr_t) ev.element; |
|
538 + vctx = verbs_get_ctx_op(context, drv_get_legacy_xrc); |
|
539 + if (vctx) |
|
540 + ibv_srq_legacy = |
|
541 + vctx->drv_get_legacy_xrc((void *) (uintptr_t) ev.element); |
|
542 + |
|
543 + event->element.srq = (ibv_srq_legacy) ? (void *)ibv_srq_legacy : |
|
544 + (void *) (uintptr_t) ev.element; |
|
545 break; |
|
546 case IBV_EVENT_GID_AVAIL: |
|
547 case IBV_EVENT_GID_UNAVAIL: |
|
548 @@ -310,6 +326,12 @@ |
|
549 |
|
550 void __ibv_ack_async_event(struct ibv_async_event *event) |
|
551 { |
|
552 + int is_legacy_xrc = 0; |
|
553 + if (event->event_type & IBV_XRC_QP_EVENT_FLAG) { |
|
554 + event->event_type ^= IBV_XRC_QP_EVENT_FLAG; |
|
555 + is_legacy_xrc = 1; |
|
556 + } |
|
557 + |
|
558 switch (event->event_type) { |
|
559 case IBV_EVENT_CQ_ERR: |
|
560 { |
|
561 @@ -334,6 +356,16 @@ |
|
562 { |
|
563 struct ibv_qp *qp = event->element.qp; |
|
564 |
|
565 + if (is_legacy_xrc) { |
|
566 + qp = ibv_find_xrc_qp(event->element.xrc_qp_num); |
|
567 + if (!qp || qp->qp_num != event->element.xrc_qp_num) { |
|
568 + fprintf(stderr, PFX "Warning: ibv_ack_async_event, " |
|
569 + "XRC qpn=%u wasn't found\n", |
|
570 + event->element.xrc_qp_num); |
|
571 + return; |
|
572 + } |
|
573 + } |
|
574 + |
|
575 pthread_mutex_lock(&qp->mutex); |
|
576 ++qp->events_completed; |
|
577 pthread_cond_signal(&qp->cond); |
|
578 @@ -347,6 +379,12 @@ |
|
579 { |
|
580 struct ibv_srq *srq = event->element.srq; |
|
581 |
|
582 + if (srq->handle == LEGACY_XRC_SRQ_HANDLE) { |
|
583 + struct ibv_srq_legacy *ibv_srq_legacy = |
|
584 + (struct ibv_srq_legacy *) srq; |
|
585 + srq = ibv_srq_legacy->ibv_srq; |
|
586 + } |
|
587 + |
|
588 pthread_mutex_lock(&srq->mutex); |
|
589 ++srq->events_completed; |
|
590 pthread_cond_signal(&srq->cond); |
|
591 diff -r f8684a1d3f02 src/ibverbs.h |
|
592 --- a/src/ibverbs.h Mon Nov 21 11:48:20 2016 -0800 |
|
593 +++ b/src/ibverbs.h Mon Mar 20 14:32:42 2017 -0700 |
|
594 @@ -85,6 +85,7 @@ |
|
595 extern HIDDEN int abi_ver; |
|
596 |
|
597 HIDDEN int ibverbs_init(struct ibv_device ***list); |
|
598 +HIDDEN struct ibv_qp *ibv_find_xrc_qp(uint32_t qpn); |
|
599 |
|
600 #define IBV_INIT_CMD(cmd, size, opcode) \ |
|
601 do { \ |
|
602 diff -r f8684a1d3f02 src/libibverbs.map |
|
603 --- a/src/libibverbs.map Mon Nov 21 11:48:20 2016 -0800 |
|
604 +++ b/src/libibverbs.map Mon Mar 20 14:32:42 2017 -0700 |
|
605 @@ -124,4 +124,7 @@ |
|
606 ibv_cmd_create_qp_ex; |
|
607 ibv_cmd_open_qp; |
|
608 |
|
609 + ibv_open_xrc_domain; |
|
610 + ibv_create_xrc_srq; |
|
611 + ibv_close_xrc_domain; |
|
612 } IBVERBS_1.0; |
|
613 diff -r f8684a1d3f02 src/verbs.c |
|
614 --- a/src/verbs.c Mon Nov 21 11:48:20 2016 -0800 |
|
615 +++ b/src/verbs.c Mon Mar 20 14:32:42 2017 -0700 |
|
616 @@ -41,6 +41,7 @@ |
|
617 #include <stdlib.h> |
|
618 #include <errno.h> |
|
619 #include <string.h> |
|
620 +#include <search.h> |
|
621 #if defined(__SVR4) && defined(__sun) |
|
622 #include <fcntl.h> |
|
623 #include <sys/stat.h> |
|
624 @@ -854,3 +855,208 @@ |
|
625 return qp->context->ops.detach_mcast(qp, gid, lid); |
|
626 } |
|
627 default_symver(__ibv_detach_mcast, ibv_detach_mcast); |
|
628 + |
|
629 + |
|
630 +/* XRC compatibility layer */ |
|
631 +struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context, |
|
632 + int fd, int oflag) |
|
633 +{ |
|
634 + |
|
635 + struct ibv_xrcd *ibv_xrcd; |
|
636 + struct ibv_xrcd_init_attr xrcd_init_attr; |
|
637 + |
|
638 + memset(&xrcd_init_attr, 0, sizeof(xrcd_init_attr)); |
|
639 + |
|
640 + xrcd_init_attr.fd = fd; |
|
641 + xrcd_init_attr.oflags = oflag; |
|
642 + |
|
643 + xrcd_init_attr.comp_mask = IBV_XRCD_INIT_ATTR_FD | |
|
644 + IBV_XRCD_INIT_ATTR_OFLAGS; |
|
645 + |
|
646 + ibv_xrcd = ibv_open_xrcd(context, &xrcd_init_attr); |
|
647 + if (!ibv_xrcd) |
|
648 + return NULL; |
|
649 + |
|
650 + return (struct ibv_xrc_domain *)ibv_xrcd; |
|
651 + |
|
652 +} |
|
653 + |
|
654 + |
|
655 +struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd, |
|
656 + struct ibv_xrc_domain *xrc_domain, |
|
657 + struct ibv_cq *xrc_cq, |
|
658 + struct ibv_srq_init_attr *srq_init_attr) |
|
659 +{ |
|
660 + |
|
661 + struct ibv_srq_init_attr_ex ibv_srq_init_attr_ex; |
|
662 + struct ibv_srq_legacy *ibv_srq_legacy; |
|
663 + struct ibv_srq *ibv_srq; |
|
664 + uint32_t xrc_srq_num; |
|
665 + struct verbs_context *vctx; |
|
666 + |
|
667 + vctx = verbs_get_ctx_op(pd->context, drv_set_legacy_xrc); |
|
668 + if (!vctx) { |
|
669 + errno = ENOSYS; |
|
670 + return NULL; |
|
671 + } |
|
672 + memset(&ibv_srq_init_attr_ex, 0, sizeof ibv_srq_init_attr_ex); |
|
673 + |
|
674 + ibv_srq_init_attr_ex.xrcd = (struct ibv_xrcd *)xrc_domain; |
|
675 + ibv_srq_init_attr_ex.comp_mask = IBV_SRQ_INIT_ATTR_XRCD | |
|
676 + IBV_SRQ_INIT_ATTR_TYPE | |
|
677 + IBV_SRQ_INIT_ATTR_CQ | IBV_SRQ_INIT_ATTR_PD; |
|
678 + |
|
679 + ibv_srq_init_attr_ex.cq = xrc_cq; |
|
680 + ibv_srq_init_attr_ex.pd = pd; |
|
681 + ibv_srq_init_attr_ex.srq_type = IBV_SRQT_XRC; |
|
682 + |
|
683 + ibv_srq_init_attr_ex.attr.max_sge = srq_init_attr->attr.max_sge; |
|
684 + ibv_srq_init_attr_ex.attr.max_wr = srq_init_attr->attr.max_wr; |
|
685 + ibv_srq_init_attr_ex.attr.srq_limit = srq_init_attr->attr.srq_limit; |
|
686 + ibv_srq_init_attr_ex.srq_context = srq_init_attr->srq_context; |
|
687 + |
|
688 + ibv_srq = ibv_create_srq_ex(pd->context, &ibv_srq_init_attr_ex); |
|
689 + if (!ibv_srq) |
|
690 + return NULL; |
|
691 + |
|
692 + if (ibv_srq->handle == LEGACY_XRC_SRQ_HANDLE) { |
|
693 + |
|
694 + struct ibv_srq *ibv_srq_tmp = ibv_srq; |
|
695 + int ret; |
|
696 + |
|
697 + ibv_srq = ibv_create_srq_ex(pd->context, &ibv_srq_init_attr_ex); |
|
698 + |
|
699 + ret = ibv_destroy_srq(ibv_srq_tmp); |
|
700 + if (ret) { |
|
701 + fprintf(stderr, PFX "ibv_create_xrc_srq, " |
|
702 + "fail to destroy intermediate srq\n"); |
|
703 + return NULL; |
|
704 + } |
|
705 + |
|
706 + if (!ibv_srq) |
|
707 + return NULL; |
|
708 + |
|
709 + if (ibv_srq->handle == LEGACY_XRC_SRQ_HANDLE) { |
|
710 + ret = ibv_destroy_srq(ibv_srq); |
|
711 + if (ret) |
|
712 + fprintf(stderr, PFX "ibv_create_xrc_srq, " |
|
713 + "fail to destroy intermediate srq\n"); |
|
714 + errno = EAGAIN; |
|
715 + return NULL; |
|
716 + } |
|
717 + } |
|
718 + |
|
719 + ibv_srq_legacy = calloc(1, sizeof(*ibv_srq_legacy)); |
|
720 + if (!ibv_srq_legacy) { |
|
721 + errno = ENOMEM; |
|
722 + goto err; |
|
723 + } |
|
724 + |
|
725 + if (ibv_get_srq_num(ibv_srq, &xrc_srq_num)) |
|
726 + goto err_free; |
|
727 + |
|
728 + ibv_srq_legacy->ibv_srq = ibv_srq; |
|
729 + ibv_srq_legacy->xrc_srq_num = xrc_srq_num; |
|
730 + |
|
731 + /* Setting the bin compat fields */ |
|
732 + ibv_srq_legacy->xrc_srq_num_bin_compat = xrc_srq_num; |
|
733 + ibv_srq_legacy->xrc_domain_bin_compat = xrc_domain; |
|
734 + ibv_srq_legacy->xrc_cq_bin_compat = xrc_cq; |
|
735 + ibv_srq_legacy->context = pd->context; |
|
736 + ibv_srq_legacy->srq_context = srq_init_attr->srq_context; |
|
737 + ibv_srq_legacy->pd = pd; |
|
738 + /* |
|
739 + * Set an indication that this is a legacy structure. For legacy structures, |
|
740 + * we should use the internal ibv_srq. |
|
741 + */ |
|
742 + ibv_srq_legacy->handle = LEGACY_XRC_SRQ_HANDLE; |
|
743 + ibv_srq_legacy->xrc_domain = xrc_domain; |
|
744 + ibv_srq_legacy->xrc_cq = xrc_cq; |
|
745 + ibv_srq_legacy->events_completed = 0; |
|
746 + |
|
747 + srq_init_attr->attr.max_wr = ibv_srq_init_attr_ex.attr.max_wr; |
|
748 + srq_init_attr->attr.max_sge = ibv_srq_init_attr_ex.attr.max_sge; |
|
749 + |
|
750 + vctx->drv_set_legacy_xrc(ibv_srq, ibv_srq_legacy); |
|
751 + return (struct ibv_srq *)(ibv_srq_legacy); |
|
752 + |
|
753 +err_free: |
|
754 + free(ibv_srq_legacy); |
|
755 +err: |
|
756 + ibv_destroy_srq(ibv_srq); |
|
757 + return NULL; |
|
758 + |
|
759 +} |
|
760 + |
|
761 +static pthread_mutex_t xrc_tree_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
762 +static void *ibv_xrc_qp_tree; |
|
763 + |
|
764 +static int xrc_qp_compare(const void *a, const void *b) |
|
765 +{ |
|
766 + |
|
767 + if ((*(uint32_t *) a) < (*(uint32_t *) b)) |
|
768 + return -1; |
|
769 + else if ((*(uint32_t *) a) > (*(uint32_t *) b)) |
|
770 + return 1; |
|
771 + else |
|
772 + return 0; |
|
773 + |
|
774 +} |
|
775 + |
|
776 +struct ibv_qp *ibv_find_xrc_qp(uint32_t qpn) |
|
777 +{ |
|
778 + uint32_t **qpn_ptr; |
|
779 + struct ibv_qp *ibv_qp = NULL; |
|
780 + |
|
781 + pthread_mutex_lock(&xrc_tree_mutex); |
|
782 + qpn_ptr = tfind(&qpn, &ibv_xrc_qp_tree, xrc_qp_compare); |
|
783 + if (!qpn_ptr) |
|
784 + goto end; |
|
785 + |
|
786 + ibv_qp = container_of(*qpn_ptr, struct ibv_qp, qp_num); |
|
787 + |
|
788 +end: |
|
789 + pthread_mutex_unlock(&xrc_tree_mutex); |
|
790 + return ibv_qp; |
|
791 +} |
|
792 + |
|
793 +static int ibv_clear_xrc_qp(uint32_t qpn) |
|
794 +{ |
|
795 + uint32_t **qpn_ptr; |
|
796 + int ret = 0; |
|
797 + |
|
798 + pthread_mutex_lock(&xrc_tree_mutex); |
|
799 + qpn_ptr = tdelete(&qpn, &ibv_xrc_qp_tree, xrc_qp_compare); |
|
800 + if (!qpn_ptr) |
|
801 + ret = EINVAL; |
|
802 + |
|
803 + pthread_mutex_unlock(&xrc_tree_mutex); |
|
804 + return ret; |
|
805 +} |
|
806 + |
|
807 +static int ibv_store_xrc_qp(struct ibv_qp *qp) |
|
808 +{ |
|
809 + uint32_t **qpn_ptr; |
|
810 + int ret = 0; |
|
811 + |
|
812 + if (ibv_find_xrc_qp(qp->qp_num)) { |
|
813 + fprintf(stderr, PFX "ibv_store_xrc_qp failed, qpn=%u is already stored\n", |
|
814 + qp->qp_num); |
|
815 + return EEXIST; |
|
816 + } |
|
817 + |
|
818 + pthread_mutex_lock(&xrc_tree_mutex); |
|
819 + qpn_ptr = tsearch(&qp->qp_num, &ibv_xrc_qp_tree, xrc_qp_compare); |
|
820 + if (!qpn_ptr) |
|
821 + ret = EINVAL; |
|
822 + |
|
823 + pthread_mutex_unlock(&xrc_tree_mutex); |
|
824 + return ret; |
|
825 + |
|
826 +} |
|
827 + |
|
828 +int ibv_close_xrc_domain(struct ibv_xrc_domain *d) |
|
829 +{ |
|
830 + struct ibv_xrcd *ibv_xrcd = (struct ibv_xrcd *)d; |
|
831 + return ibv_close_xrcd(ibv_xrcd); |
|
832 +} |