1 /*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33 #include <config.h>
34
35 #include <string.h>
36 #include <stddef.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39
40 #include "ibverbs.h"
41
42 struct ibv_pd_1_0 {
43 struct ibv_context_1_0 *context;
44 uint32_t handle;
45
46 struct ibv_pd *real_pd;
47 };
48
49 struct ibv_mr_1_0 {
50 struct ibv_context_1_0 *context;
51 struct ibv_pd_1_0 *pd;
52 uint32_t handle;
53 uint32_t lkey;
54 uint32_t rkey;
55
56 struct ibv_mr *real_mr;
57 };
58
59 struct ibv_srq_1_0 {
60 struct ibv_context_1_0 *context;
61 void *srq_context;
62 struct ibv_pd_1_0 *pd;
63 uint32_t handle;
64
65 pthread_mutex_t mutex;
66 pthread_cond_t cond;
67 uint32_t events_completed;
68
69 struct ibv_srq *real_srq;
70 };
71
72 struct ibv_qp_init_attr_1_0 {
73 void *qp_context;
74 struct ibv_cq_1_0 *send_cq;
75 struct ibv_cq_1_0 *recv_cq;
76 struct ibv_srq_1_0 *srq;
77 struct ibv_qp_cap cap;
78 enum ibv_qp_type qp_type;
79 int sq_sig_all;
80 };
81
82 struct ibv_send_wr_1_0 {
83 struct ibv_send_wr_1_0 *next;
84 uint64_t wr_id;
85 struct ibv_sge *sg_list;
86 int num_sge;
87 enum ibv_wr_opcode opcode;
88 int send_flags;
89 __be32 imm_data;
90 union {
91 struct {
92 uint64_t remote_addr;
93 uint32_t rkey;
94 } rdma;
95 struct {
96 uint64_t remote_addr;
97 uint64_t compare_add;
98 uint64_t swap;
99 uint32_t rkey;
100 } atomic;
101 struct {
102 struct ibv_ah_1_0 *ah;
103 uint32_t remote_qpn;
104 uint32_t remote_qkey;
105 } ud;
106 } wr;
107 };
108
109 struct ibv_recv_wr_1_0 {
110 struct ibv_recv_wr_1_0 *next;
111 uint64_t wr_id;
112 struct ibv_sge *sg_list;
113 int num_sge;
114 };
115
116 struct ibv_qp_1_0 {
117 struct ibv_context_1_0 *context;
118 void *qp_context;
119 struct ibv_pd_1_0 *pd;
120 struct ibv_cq_1_0 *send_cq;
121 struct ibv_cq_1_0 *recv_cq;
122 struct ibv_srq_1_0 *srq;
123 uint32_t handle;
124 uint32_t qp_num;
125 enum ibv_qp_state state;
126 enum ibv_qp_type qp_type;
127
128 pthread_mutex_t mutex;
129 pthread_cond_t cond;
130 uint32_t events_completed;
131
132 struct ibv_qp *real_qp;
133 };
134
135 struct ibv_cq_1_0 {
136 struct ibv_context_1_0 *context;
137 void *cq_context;
138 uint32_t handle;
139 int cqe;
140
141 pthread_mutex_t mutex;
142 pthread_cond_t cond;
143 uint32_t comp_events_completed;
144 uint32_t async_events_completed;
145
146 struct ibv_cq *real_cq;
147 };
148
149 struct ibv_ah_1_0 {
150 struct ibv_context_1_0 *context;
151 struct ibv_pd_1_0 *pd;
152 uint32_t handle;
153
154 struct ibv_ah *real_ah;
155 };
156
157 struct ibv_device_1_0 {
158 void *obsolete_sysfs_dev;
159 void *obsolete_sysfs_ibdev;
160 struct ibv_device *real_device; /* was obsolete driver member */
161 struct _ibv_device_ops _ops;
162 };
163
164 struct ibv_context_ops_1_0 {
165 int (*query_device)(struct ibv_context *context,
166 struct ibv_device_attr *device_attr);
167 int (*query_port)(struct ibv_context *context, uint8_t port_num,
168 struct ibv_port_attr *port_attr);
169 struct ibv_pd * (*alloc_pd)(struct ibv_context *context);
170 int (*dealloc_pd)(struct ibv_pd *pd);
171 struct ibv_mr * (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length,
172 int access);
173 int (*dereg_mr)(struct ibv_mr *mr);
174 struct ibv_cq * (*create_cq)(struct ibv_context *context, int cqe,
175 struct ibv_comp_channel *channel,
176 int comp_vector);
177 int (*poll_cq)(struct ibv_cq_1_0 *cq, int num_entries,
178 struct ibv_wc *wc);
179 int (*req_notify_cq)(struct ibv_cq_1_0 *cq,
180 int solicited_only);
181 void (*cq_event)(struct ibv_cq *cq);
182 int (*resize_cq)(struct ibv_cq *cq, int cqe);
183 int (*destroy_cq)(struct ibv_cq *cq);
184 struct ibv_srq * (*create_srq)(struct ibv_pd *pd,
185 struct ibv_srq_init_attr *srq_init_attr);
186 int (*modify_srq)(struct ibv_srq *srq,
187 struct ibv_srq_attr *srq_attr,
188 int srq_attr_mask);
189 int (*query_srq)(struct ibv_srq *srq,
190 struct ibv_srq_attr *srq_attr);
191 int (*destroy_srq)(struct ibv_srq *srq);
192 int (*post_srq_recv)(struct ibv_srq_1_0 *srq,
193 struct ibv_recv_wr_1_0 *recv_wr,
194 struct ibv_recv_wr_1_0 **bad_recv_wr);
195 struct ibv_qp * (*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *attr);
196 int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr,
197 int attr_mask,
198 struct ibv_qp_init_attr *init_attr);
199 int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr,
200 int attr_mask);
201 int (*destroy_qp)(struct ibv_qp *qp);
202 int (*post_send)(struct ibv_qp_1_0 *qp,
203 struct ibv_send_wr_1_0 *wr,
204 struct ibv_send_wr_1_0 **bad_wr);
205 int (*post_recv)(struct ibv_qp_1_0 *qp,
206 struct ibv_recv_wr_1_0 *wr,
207 struct ibv_recv_wr_1_0 **bad_wr);
208 struct ibv_ah * (*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr);
209 int (*destroy_ah)(struct ibv_ah *ah);
210 int (*attach_mcast)(struct ibv_qp *qp, union ibv_gid *gid,
211 uint16_t lid);
212 int (*detach_mcast)(struct ibv_qp *qp, union ibv_gid *gid,
213 uint16_t lid);
214 };
215
216 struct ibv_context_1_0 {
217 struct ibv_device_1_0 *device;
218 struct ibv_context_ops_1_0 ops;
219 int cmd_fd;
220 int async_fd;
221 int num_comp_vectors;
222
223 struct ibv_context *real_context; /* was abi_compat member */
224 };
225
226 typedef struct ibv_device *(*ibv_driver_init_func_1_1)(const char *uverbs_sys_path,
227 int abi_version);
228
229 /* Hack to avoid GCC's -Wmissing-prototypes and the similar error from sparse
230 with these prototypes. Symbol versionining requires the goofy names, the
231 prototype must match the version in the historical 1.0 verbs.h.
232 */
233 struct ibv_device_1_0 **__ibv_get_device_list_1_0(int *num);
234 void __ibv_free_device_list_1_0(struct ibv_device_1_0 **list);
235 const char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device);
236 __be64 __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device);
237 struct ibv_context_1_0 *__ibv_open_device_1_0(struct ibv_device_1_0 *device);
238 int __ibv_close_device_1_0(struct ibv_context_1_0 *context);
239 int __ibv_get_async_event_1_0(struct ibv_context_1_0 *context,
240 struct ibv_async_event *event);
241 void __ibv_ack_async_event_1_0(struct ibv_async_event *event);
242 int __ibv_query_device_1_0(struct ibv_context_1_0 *context,
243 struct ibv_device_attr *device_attr);
244 int __ibv_query_port_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
245 struct ibv_port_attr *port_attr);
246 int __ibv_query_gid_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
247 int index, union ibv_gid *gid);
248 int __ibv_query_pkey_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
249 int index, __be16 *pkey);
250 struct ibv_pd_1_0 *__ibv_alloc_pd_1_0(struct ibv_context_1_0 *context);
251 int __ibv_dealloc_pd_1_0(struct ibv_pd_1_0 *pd);
252 struct ibv_mr_1_0 *__ibv_reg_mr_1_0(struct ibv_pd_1_0 *pd, void *addr,
253 size_t length, int access);
254 int __ibv_dereg_mr_1_0(struct ibv_mr_1_0 *mr);
255 struct ibv_cq_1_0 *__ibv_create_cq_1_0(struct ibv_context_1_0 *context, int cqe,
256 void *cq_context,
257 struct ibv_comp_channel *channel,
258 int comp_vector);
259 int __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe);
260 int __ibv_destroy_cq_1_0(struct ibv_cq_1_0 *cq);
261 int __ibv_get_cq_event_1_0(struct ibv_comp_channel *channel,
262 struct ibv_cq_1_0 **cq, void **cq_context);
263 void __ibv_ack_cq_events_1_0(struct ibv_cq_1_0 *cq, unsigned int nevents);
264 struct ibv_srq_1_0 *
265 __ibv_create_srq_1_0(struct ibv_pd_1_0 *pd,
266 struct ibv_srq_init_attr *srq_init_attr);
267 int __ibv_modify_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr,
268 int srq_attr_mask);
269 int __ibv_query_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr);
270 int __ibv_destroy_srq_1_0(struct ibv_srq_1_0 *srq);
271 struct ibv_qp_1_0 *
272 __ibv_create_qp_1_0(struct ibv_pd_1_0 *pd,
273 struct ibv_qp_init_attr_1_0 *qp_init_attr);
274 int __ibv_query_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
275 int attr_mask, struct ibv_qp_init_attr_1_0 *init_attr);
276 int __ibv_modify_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
277 int attr_mask);
278 int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp);
279 struct ibv_ah_1_0 *__ibv_create_ah_1_0(struct ibv_pd_1_0 *pd,
280 struct ibv_ah_attr *attr);
281 int __ibv_destroy_ah_1_0(struct ibv_ah_1_0 *ah);
282 int __ibv_attach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid,
283 uint16_t lid);
284 int __ibv_detach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid,
285 uint16_t lid);
286 void __ibv_register_driver_1_1(const char *name,
287 ibv_driver_init_func_1_1 init_func);
288
__ibv_get_device_list_1_0(int * num)289 struct ibv_device_1_0 **__ibv_get_device_list_1_0(int *num)
290 {
291 struct ibv_device **real_list;
292 struct ibv_device_1_0 **l;
293 int i, n;
294
295 real_list = ibv_get_device_list(&n);
296 if (!real_list)
297 return NULL;
298
299 l = calloc(n + 2, sizeof (struct ibv_device_1_0 *));
300 if (!l)
301 goto free_device_list;
302
303 l[0] = (void *) real_list;
304
305 for (i = 0; i < n; ++i) {
306 l[i + 1] = calloc(1, sizeof (struct ibv_device_1_0));
307 if (!l[i + 1])
308 goto fail;
309 l[i + 1]->real_device = real_list[i];
310 }
311
312 if (num)
313 *num = n;
314
315 return l + 1;
316
317 fail:
318 for (i = 1; i <= n; ++i)
319 if (l[i])
320 free(l[i]);
321 free(l);
322
323 free_device_list:
324 ibv_free_device_list(real_list);
325 return NULL;
326 }
327 symver(__ibv_get_device_list_1_0, ibv_get_device_list, IBVERBS_1.0);
328
__ibv_free_device_list_1_0(struct ibv_device_1_0 ** list)329 void __ibv_free_device_list_1_0(struct ibv_device_1_0 **list)
330 {
331 struct ibv_device_1_0 **l = list;
332
333 while (*l) {
334 free(*l);
335 ++l;
336 }
337
338 ibv_free_device_list((void *) list[-1]);
339 free(list - 1);
340 }
341 symver(__ibv_free_device_list_1_0, ibv_free_device_list, IBVERBS_1.0);
342
__ibv_get_device_name_1_0(struct ibv_device_1_0 * device)343 const char *__ibv_get_device_name_1_0(struct ibv_device_1_0 *device)
344 {
345 return ibv_get_device_name(device->real_device);
346 }
347 symver(__ibv_get_device_name_1_0, ibv_get_device_name, IBVERBS_1.0);
348
__ibv_get_device_guid_1_0(struct ibv_device_1_0 * device)349 __be64 __ibv_get_device_guid_1_0(struct ibv_device_1_0 *device)
350 {
351 return ibv_get_device_guid(device->real_device);
352 }
353 symver(__ibv_get_device_guid_1_0, ibv_get_device_guid, IBVERBS_1.0);
354
poll_cq_wrapper_1_0(struct ibv_cq_1_0 * cq,int num_entries,struct ibv_wc * wc)355 static int poll_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int num_entries,
356 struct ibv_wc *wc)
357 {
358 return cq->context->real_context->ops.poll_cq(cq->real_cq, num_entries, wc);
359 }
360
req_notify_cq_wrapper_1_0(struct ibv_cq_1_0 * cq,int sol_only)361 static int req_notify_cq_wrapper_1_0(struct ibv_cq_1_0 *cq, int sol_only)
362 {
363 return cq->context->real_context->ops.req_notify_cq(cq->real_cq, sol_only);
364 }
365
post_srq_recv_wrapper_1_0(struct ibv_srq_1_0 * srq,struct ibv_recv_wr_1_0 * wr,struct ibv_recv_wr_1_0 ** bad_wr)366 static int post_srq_recv_wrapper_1_0(struct ibv_srq_1_0 *srq, struct ibv_recv_wr_1_0 *wr,
367 struct ibv_recv_wr_1_0 **bad_wr)
368 {
369 struct ibv_recv_wr_1_0 *w;
370 struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
371 int ret;
372
373 for (w = wr; w; w = w->next) {
374 real_wr = alloca(sizeof *real_wr);
375 real_wr->wr_id = w->wr_id;
376 real_wr->sg_list = w->sg_list;
377 real_wr->num_sge = w->num_sge;
378 real_wr->next = NULL;
379 if (tail_wr)
380 tail_wr->next = real_wr;
381 else
382 head_wr = real_wr;
383
384 tail_wr = real_wr;
385 }
386
387 ret = srq->context->real_context->ops.post_srq_recv(srq->real_srq, head_wr,
388 &real_bad_wr);
389
390 if (ret) {
391 for (real_wr = head_wr, w = wr;
392 real_wr;
393 real_wr = real_wr->next, w = w->next)
394 if (real_wr == real_bad_wr) {
395 *bad_wr = w;
396 break;
397 }
398 }
399
400 return ret;
401 }
402
post_send_wrapper_1_0(struct ibv_qp_1_0 * qp,struct ibv_send_wr_1_0 * wr,struct ibv_send_wr_1_0 ** bad_wr)403 static int post_send_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_send_wr_1_0 *wr,
404 struct ibv_send_wr_1_0 **bad_wr)
405 {
406 struct ibv_send_wr_1_0 *w;
407 struct ibv_send_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
408 int is_ud = qp->qp_type == IBV_QPT_UD;
409 int ret;
410
411 for (w = wr; w; w = w->next) {
412 real_wr = alloca(sizeof *real_wr);
413 real_wr->wr_id = w->wr_id;
414 real_wr->next = NULL;
415
416 #define TEST_SIZE_2_POINT(f1, f2) \
417 ((offsetof(struct ibv_send_wr, f1) - offsetof(struct ibv_send_wr, f2)) \
418 == offsetof(struct ibv_send_wr_1_0, f1) - offsetof(struct ibv_send_wr_1_0, f2))
419 #define TEST_SIZE_TO_END(f1) \
420 ((sizeof(struct ibv_send_wr) - offsetof(struct ibv_send_wr, f1)) == \
421 (sizeof(struct ibv_send_wr_1_0) - offsetof(struct ibv_send_wr_1_0, f1)))
422
423 if (TEST_SIZE_TO_END (sg_list))
424 memcpy(&real_wr->sg_list, &w->sg_list, sizeof *real_wr
425 - offsetof(struct ibv_send_wr, sg_list));
426 else if (TEST_SIZE_2_POINT (imm_data, sg_list) &&
427 TEST_SIZE_TO_END (wr)) {
428 /* we have alignment up to wr, but padding between
429 * imm_data and wr, and we know wr itself is the
430 * same size */
431 memcpy(&real_wr->sg_list, &w->sg_list,
432 offsetof(struct ibv_send_wr, imm_data) -
433 offsetof(struct ibv_send_wr, sg_list) +
434 sizeof real_wr->imm_data);
435 memcpy(&real_wr->wr, &w->wr, sizeof real_wr->wr);
436 } else {
437 real_wr->sg_list = w->sg_list;
438 real_wr->num_sge = w->num_sge;
439 real_wr->opcode = w->opcode;
440 real_wr->send_flags = w->send_flags;
441 real_wr->imm_data = w->imm_data;
442 if (TEST_SIZE_TO_END (wr))
443 memcpy(&real_wr->wr, &w->wr,
444 sizeof real_wr->wr);
445 else {
446 real_wr->wr.atomic.remote_addr =
447 w->wr.atomic.remote_addr;
448 real_wr->wr.atomic.compare_add =
449 w->wr.atomic.compare_add;
450 real_wr->wr.atomic.swap =
451 w->wr.atomic.swap;
452 real_wr->wr.atomic.rkey =
453 w->wr.atomic.rkey;
454 }
455 }
456
457 if (is_ud)
458 real_wr->wr.ud.ah = w->wr.ud.ah->real_ah;
459
460 if (tail_wr)
461 tail_wr->next = real_wr;
462 else
463 head_wr = real_wr;
464
465 tail_wr = real_wr;
466 }
467
468 ret = qp->context->real_context->ops.post_send(qp->real_qp, head_wr,
469 &real_bad_wr);
470
471 if (ret) {
472 for (real_wr = head_wr, w = wr;
473 real_wr;
474 real_wr = real_wr->next, w = w->next)
475 if (real_wr == real_bad_wr) {
476 *bad_wr = w;
477 break;
478 }
479 }
480
481 return ret;
482 }
483
post_recv_wrapper_1_0(struct ibv_qp_1_0 * qp,struct ibv_recv_wr_1_0 * wr,struct ibv_recv_wr_1_0 ** bad_wr)484 static int post_recv_wrapper_1_0(struct ibv_qp_1_0 *qp, struct ibv_recv_wr_1_0 *wr,
485 struct ibv_recv_wr_1_0 **bad_wr)
486 {
487 struct ibv_recv_wr_1_0 *w;
488 struct ibv_recv_wr *real_wr, *head_wr = NULL, *tail_wr = NULL, *real_bad_wr;
489 int ret;
490
491 for (w = wr; w; w = w->next) {
492 real_wr = alloca(sizeof *real_wr);
493 real_wr->wr_id = w->wr_id;
494 real_wr->sg_list = w->sg_list;
495 real_wr->num_sge = w->num_sge;
496 real_wr->next = NULL;
497 if (tail_wr)
498 tail_wr->next = real_wr;
499 else
500 head_wr = real_wr;
501
502 tail_wr = real_wr;
503 }
504
505 ret = qp->context->real_context->ops.post_recv(qp->real_qp, head_wr,
506 &real_bad_wr);
507
508 if (ret) {
509 for (real_wr = head_wr, w = wr;
510 real_wr;
511 real_wr = real_wr->next, w = w->next)
512 if (real_wr == real_bad_wr) {
513 *bad_wr = w;
514 break;
515 }
516 }
517
518 return ret;
519 }
520
__ibv_open_device_1_0(struct ibv_device_1_0 * device)521 struct ibv_context_1_0 *__ibv_open_device_1_0(struct ibv_device_1_0 *device)
522 {
523 struct ibv_context *real_ctx;
524 struct ibv_context_1_0 *ctx;
525
526 ctx = malloc(sizeof *ctx);
527 if (!ctx)
528 return NULL;
529
530 real_ctx = ibv_open_device(device->real_device);
531 if (!real_ctx) {
532 free(ctx);
533 return NULL;
534 }
535
536 ctx->device = device;
537 ctx->real_context = real_ctx;
538
539 ctx->ops.poll_cq = poll_cq_wrapper_1_0;
540 ctx->ops.req_notify_cq = req_notify_cq_wrapper_1_0;
541 ctx->ops.post_send = post_send_wrapper_1_0;
542 ctx->ops.post_recv = post_recv_wrapper_1_0;
543 ctx->ops.post_srq_recv = post_srq_recv_wrapper_1_0;
544
545 return ctx;
546 }
547 symver(__ibv_open_device_1_0, ibv_open_device, IBVERBS_1.0);
548
__ibv_close_device_1_0(struct ibv_context_1_0 * context)549 int __ibv_close_device_1_0(struct ibv_context_1_0 *context)
550 {
551 int ret;
552
553 ret = ibv_close_device(context->real_context);
554 if (ret)
555 return ret;
556
557 free(context);
558 return 0;
559 }
560 symver(__ibv_close_device_1_0, ibv_close_device, IBVERBS_1.0);
561
__ibv_get_async_event_1_0(struct ibv_context_1_0 * context,struct ibv_async_event * event)562 int __ibv_get_async_event_1_0(struct ibv_context_1_0 *context,
563 struct ibv_async_event *event)
564 {
565 int ret;
566
567 ret = ibv_get_async_event(context->real_context, event);
568 if (ret)
569 return ret;
570
571 switch (event->event_type) {
572 case IBV_EVENT_CQ_ERR:
573 event->element.cq = event->element.cq->cq_context;
574 break;
575
576 case IBV_EVENT_QP_FATAL:
577 case IBV_EVENT_QP_REQ_ERR:
578 case IBV_EVENT_QP_ACCESS_ERR:
579 case IBV_EVENT_COMM_EST:
580 case IBV_EVENT_SQ_DRAINED:
581 case IBV_EVENT_PATH_MIG:
582 case IBV_EVENT_PATH_MIG_ERR:
583 case IBV_EVENT_QP_LAST_WQE_REACHED:
584 event->element.qp = event->element.qp->qp_context;
585 break;
586
587 case IBV_EVENT_SRQ_ERR:
588 case IBV_EVENT_SRQ_LIMIT_REACHED:
589 event->element.srq = event->element.srq->srq_context;
590 break;
591
592 default:
593 break;
594 }
595
596 return ret;
597 }
598 symver(__ibv_get_async_event_1_0, ibv_get_async_event, IBVERBS_1.0);
599
__ibv_ack_async_event_1_0(struct ibv_async_event * event)600 void __ibv_ack_async_event_1_0(struct ibv_async_event *event)
601 {
602 struct ibv_async_event real_event = *event;
603
604 switch (event->event_type) {
605 case IBV_EVENT_CQ_ERR:
606 real_event.element.cq =
607 ((struct ibv_cq_1_0 *) event->element.cq)->real_cq;
608 break;
609
610 case IBV_EVENT_QP_FATAL:
611 case IBV_EVENT_QP_REQ_ERR:
612 case IBV_EVENT_QP_ACCESS_ERR:
613 case IBV_EVENT_COMM_EST:
614 case IBV_EVENT_SQ_DRAINED:
615 case IBV_EVENT_PATH_MIG:
616 case IBV_EVENT_PATH_MIG_ERR:
617 case IBV_EVENT_QP_LAST_WQE_REACHED:
618 real_event.element.qp =
619 ((struct ibv_qp_1_0 *) event->element.qp)->real_qp;
620 break;
621
622 case IBV_EVENT_SRQ_ERR:
623 case IBV_EVENT_SRQ_LIMIT_REACHED:
624 real_event.element.srq =
625 ((struct ibv_srq_1_0 *) event->element.srq)->real_srq;
626 break;
627
628 default:
629 break;
630 }
631
632 ibv_ack_async_event(&real_event);
633 }
634 symver(__ibv_ack_async_event_1_0, ibv_ack_async_event, IBVERBS_1.0);
635
__ibv_query_device_1_0(struct ibv_context_1_0 * context,struct ibv_device_attr * device_attr)636 int __ibv_query_device_1_0(struct ibv_context_1_0 *context,
637 struct ibv_device_attr *device_attr)
638 {
639 return ibv_query_device(context->real_context, device_attr);
640 }
641 symver(__ibv_query_device_1_0, ibv_query_device, IBVERBS_1.0);
642
__ibv_query_port_1_0(struct ibv_context_1_0 * context,uint8_t port_num,struct ibv_port_attr * port_attr)643 int __ibv_query_port_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
644 struct ibv_port_attr *port_attr)
645 {
646 return ibv_query_port(context->real_context, port_num, port_attr);
647 }
648 symver(__ibv_query_port_1_0, ibv_query_port, IBVERBS_1.0);
649
__ibv_query_gid_1_0(struct ibv_context_1_0 * context,uint8_t port_num,int index,union ibv_gid * gid)650 int __ibv_query_gid_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
651 int index, union ibv_gid *gid)
652 {
653 return ibv_query_gid(context->real_context, port_num, index, gid);
654 }
655 symver(__ibv_query_gid_1_0, ibv_query_gid, IBVERBS_1.0);
656
__ibv_query_pkey_1_0(struct ibv_context_1_0 * context,uint8_t port_num,int index,__be16 * pkey)657 int __ibv_query_pkey_1_0(struct ibv_context_1_0 *context, uint8_t port_num,
658 int index, __be16 *pkey)
659 {
660 return ibv_query_pkey(context->real_context, port_num, index, pkey);
661 }
662 symver(__ibv_query_pkey_1_0, ibv_query_pkey, IBVERBS_1.0);
663
__ibv_alloc_pd_1_0(struct ibv_context_1_0 * context)664 struct ibv_pd_1_0 *__ibv_alloc_pd_1_0(struct ibv_context_1_0 *context)
665 {
666 struct ibv_pd *real_pd;
667 struct ibv_pd_1_0 *pd;
668
669 pd = malloc(sizeof *pd);
670 if (!pd)
671 return NULL;
672
673 real_pd = ibv_alloc_pd(context->real_context);
674 if (!real_pd) {
675 free(pd);
676 return NULL;
677 }
678
679 pd->context = context;
680 pd->real_pd = real_pd;
681
682 return pd;
683 }
684 symver(__ibv_alloc_pd_1_0, ibv_alloc_pd, IBVERBS_1.0);
685
__ibv_dealloc_pd_1_0(struct ibv_pd_1_0 * pd)686 int __ibv_dealloc_pd_1_0(struct ibv_pd_1_0 *pd)
687 {
688 int ret;
689
690 ret = ibv_dealloc_pd(pd->real_pd);
691 if (ret)
692 return ret;
693
694 free(pd);
695 return 0;
696 }
697 symver(__ibv_dealloc_pd_1_0, ibv_dealloc_pd, IBVERBS_1.0);
698
__ibv_reg_mr_1_0(struct ibv_pd_1_0 * pd,void * addr,size_t length,int access)699 struct ibv_mr_1_0 *__ibv_reg_mr_1_0(struct ibv_pd_1_0 *pd, void *addr,
700 size_t length, int access)
701 {
702 struct ibv_mr *real_mr;
703 struct ibv_mr_1_0 *mr;
704
705 mr = malloc(sizeof *mr);
706 if (!mr)
707 return NULL;
708
709 real_mr = ibv_reg_mr(pd->real_pd, addr, length, access);
710 if (!real_mr) {
711 free(mr);
712 return NULL;
713 }
714
715 mr->context = pd->context;
716 mr->pd = pd;
717 mr->lkey = real_mr->lkey;
718 mr->rkey = real_mr->rkey;
719 mr->real_mr = real_mr;
720
721 return mr;
722 }
723 symver(__ibv_reg_mr_1_0, ibv_reg_mr, IBVERBS_1.0);
724
__ibv_dereg_mr_1_0(struct ibv_mr_1_0 * mr)725 int __ibv_dereg_mr_1_0(struct ibv_mr_1_0 *mr)
726 {
727 int ret;
728
729 ret = ibv_dereg_mr(mr->real_mr);
730 if (ret)
731 return ret;
732
733 free(mr);
734 return 0;
735 }
736 symver(__ibv_dereg_mr_1_0, ibv_dereg_mr, IBVERBS_1.0);
737
__ibv_create_cq_1_0(struct ibv_context_1_0 * context,int cqe,void * cq_context,struct ibv_comp_channel * channel,int comp_vector)738 struct ibv_cq_1_0 *__ibv_create_cq_1_0(struct ibv_context_1_0 *context, int cqe,
739 void *cq_context,
740 struct ibv_comp_channel *channel,
741 int comp_vector)
742 {
743 struct ibv_cq *real_cq;
744 struct ibv_cq_1_0 *cq;
745
746 cq = malloc(sizeof *cq);
747 if (!cq)
748 return NULL;
749
750 real_cq = ibv_create_cq(context->real_context, cqe, cq_context,
751 channel, comp_vector);
752 if (!real_cq) {
753 free(cq);
754 return NULL;
755 }
756
757 cq->context = context;
758 cq->cq_context = cq_context;
759 cq->cqe = cqe;
760 cq->real_cq = real_cq;
761
762 real_cq->cq_context = cq;
763
764 return cq;
765 }
766 symver(__ibv_create_cq_1_0, ibv_create_cq, IBVERBS_1.0);
767
__ibv_resize_cq_1_0(struct ibv_cq_1_0 * cq,int cqe)768 int __ibv_resize_cq_1_0(struct ibv_cq_1_0 *cq, int cqe)
769 {
770 return ibv_resize_cq(cq->real_cq, cqe);
771 }
772 symver(__ibv_resize_cq_1_0, ibv_resize_cq, IBVERBS_1.0);
773
__ibv_destroy_cq_1_0(struct ibv_cq_1_0 * cq)774 int __ibv_destroy_cq_1_0(struct ibv_cq_1_0 *cq)
775 {
776 int ret;
777
778 ret = ibv_destroy_cq(cq->real_cq);
779 if (ret)
780 return ret;
781
782 free(cq);
783 return 0;
784 }
785 symver(__ibv_destroy_cq_1_0, ibv_destroy_cq, IBVERBS_1.0);
786
__ibv_get_cq_event_1_0(struct ibv_comp_channel * channel,struct ibv_cq_1_0 ** cq,void ** cq_context)787 int __ibv_get_cq_event_1_0(struct ibv_comp_channel *channel,
788 struct ibv_cq_1_0 **cq, void **cq_context)
789 {
790 struct ibv_cq *real_cq;
791 void *cq_ptr;
792 int ret;
793
794 ret = ibv_get_cq_event(channel, &real_cq, &cq_ptr);
795 if (ret)
796 return ret;
797
798 *cq = cq_ptr;
799 *cq_context = (*cq)->cq_context;
800
801 return 0;
802 }
803 symver(__ibv_get_cq_event_1_0, ibv_get_cq_event, IBVERBS_1.0);
804
__ibv_ack_cq_events_1_0(struct ibv_cq_1_0 * cq,unsigned int nevents)805 void __ibv_ack_cq_events_1_0(struct ibv_cq_1_0 *cq, unsigned int nevents)
806 {
807 ibv_ack_cq_events(cq->real_cq, nevents);
808 }
809 symver(__ibv_ack_cq_events_1_0, ibv_ack_cq_events, IBVERBS_1.0);
810
__ibv_create_srq_1_0(struct ibv_pd_1_0 * pd,struct ibv_srq_init_attr * srq_init_attr)811 struct ibv_srq_1_0 *__ibv_create_srq_1_0(struct ibv_pd_1_0 *pd,
812 struct ibv_srq_init_attr *srq_init_attr)
813 {
814 struct ibv_srq *real_srq;
815 struct ibv_srq_1_0 *srq;
816
817 srq = malloc(sizeof *srq);
818 if (!srq)
819 return NULL;
820
821 real_srq = ibv_create_srq(pd->real_pd, srq_init_attr);
822 if (!real_srq) {
823 free(srq);
824 return NULL;
825 }
826
827 srq->context = pd->context;
828 srq->srq_context = srq_init_attr->srq_context;
829 srq->pd = pd;
830 srq->real_srq = real_srq;
831
832 real_srq->srq_context = srq;
833
834 return srq;
835 }
836 symver(__ibv_create_srq_1_0, ibv_create_srq, IBVERBS_1.0);
837
__ibv_modify_srq_1_0(struct ibv_srq_1_0 * srq,struct ibv_srq_attr * srq_attr,int srq_attr_mask)838 int __ibv_modify_srq_1_0(struct ibv_srq_1_0 *srq,
839 struct ibv_srq_attr *srq_attr,
840 int srq_attr_mask)
841 {
842 return ibv_modify_srq(srq->real_srq, srq_attr, srq_attr_mask);
843 }
844 symver(__ibv_modify_srq_1_0, ibv_modify_srq, IBVERBS_1.0);
845
__ibv_query_srq_1_0(struct ibv_srq_1_0 * srq,struct ibv_srq_attr * srq_attr)846 int __ibv_query_srq_1_0(struct ibv_srq_1_0 *srq, struct ibv_srq_attr *srq_attr)
847 {
848 return ibv_query_srq(srq->real_srq, srq_attr);
849 }
850 symver(__ibv_query_srq_1_0, ibv_query_srq, IBVERBS_1.0);
851
__ibv_destroy_srq_1_0(struct ibv_srq_1_0 * srq)852 int __ibv_destroy_srq_1_0(struct ibv_srq_1_0 *srq)
853 {
854 int ret;
855
856 ret = ibv_destroy_srq(srq->real_srq);
857 if (ret)
858 return ret;
859
860 free(srq);
861 return 0;
862 }
863 symver(__ibv_destroy_srq_1_0, ibv_destroy_srq, IBVERBS_1.0);
864
__ibv_create_qp_1_0(struct ibv_pd_1_0 * pd,struct ibv_qp_init_attr_1_0 * qp_init_attr)865 struct ibv_qp_1_0 *__ibv_create_qp_1_0(struct ibv_pd_1_0 *pd,
866 struct ibv_qp_init_attr_1_0 *qp_init_attr)
867 {
868 struct ibv_qp *real_qp;
869 struct ibv_qp_1_0 *qp;
870 struct ibv_qp_init_attr real_init_attr;
871
872 qp = malloc(sizeof *qp);
873 if (!qp)
874 return NULL;
875
876 real_init_attr.qp_context = qp_init_attr->qp_context;
877 real_init_attr.send_cq = qp_init_attr->send_cq->real_cq;
878 real_init_attr.recv_cq = qp_init_attr->recv_cq->real_cq;
879 real_init_attr.srq = qp_init_attr->srq ?
880 qp_init_attr->srq->real_srq : NULL;
881 real_init_attr.cap = qp_init_attr->cap;
882 real_init_attr.qp_type = qp_init_attr->qp_type;
883 real_init_attr.sq_sig_all = qp_init_attr->sq_sig_all;
884
885 real_qp = ibv_create_qp(pd->real_pd, &real_init_attr);
886 if (!real_qp) {
887 free(qp);
888 return NULL;
889 }
890
891 qp->context = pd->context;
892 qp->qp_context = qp_init_attr->qp_context;
893 qp->pd = pd;
894 qp->send_cq = qp_init_attr->send_cq;
895 qp->recv_cq = qp_init_attr->recv_cq;
896 qp->srq = qp_init_attr->srq;
897 qp->qp_type = qp_init_attr->qp_type;
898 qp->qp_num = real_qp->qp_num;
899 qp->real_qp = real_qp;
900
901 qp_init_attr->cap = real_init_attr.cap;
902
903 real_qp->qp_context = qp;
904
905 return qp;
906 }
907 symver(__ibv_create_qp_1_0, ibv_create_qp, IBVERBS_1.0);
908
__ibv_query_qp_1_0(struct ibv_qp_1_0 * qp,struct ibv_qp_attr * attr,int attr_mask,struct ibv_qp_init_attr_1_0 * init_attr)909 int __ibv_query_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
910 int attr_mask,
911 struct ibv_qp_init_attr_1_0 *init_attr)
912 {
913 struct ibv_qp_init_attr real_init_attr;
914 int ret;
915
916 ret = ibv_query_qp(qp->real_qp, attr, attr_mask, &real_init_attr);
917 if (ret)
918 return ret;
919
920 init_attr->qp_context = qp->qp_context;
921 init_attr->send_cq = real_init_attr.send_cq->cq_context;
922 init_attr->recv_cq = real_init_attr.recv_cq->cq_context;
923 init_attr->srq = real_init_attr.srq->srq_context;
924 init_attr->qp_type = real_init_attr.qp_type;
925 init_attr->cap = real_init_attr.cap;
926 init_attr->sq_sig_all = real_init_attr.sq_sig_all;
927
928 return 0;
929 }
930 symver(__ibv_query_qp_1_0, ibv_query_qp, IBVERBS_1.0);
931
__ibv_modify_qp_1_0(struct ibv_qp_1_0 * qp,struct ibv_qp_attr * attr,int attr_mask)932 int __ibv_modify_qp_1_0(struct ibv_qp_1_0 *qp, struct ibv_qp_attr *attr,
933 int attr_mask)
934 {
935 return ibv_modify_qp(qp->real_qp, attr, attr_mask);
936 }
937 symver(__ibv_modify_qp_1_0, ibv_modify_qp, IBVERBS_1.0);
938
__ibv_destroy_qp_1_0(struct ibv_qp_1_0 * qp)939 int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp)
940 {
941 int ret;
942
943 ret = ibv_destroy_qp(qp->real_qp);
944 if (ret)
945 return ret;
946
947 free(qp);
948 return 0;
949 }
950 symver(__ibv_destroy_qp_1_0, ibv_destroy_qp, IBVERBS_1.0);
951
__ibv_create_ah_1_0(struct ibv_pd_1_0 * pd,struct ibv_ah_attr * attr)952 struct ibv_ah_1_0 *__ibv_create_ah_1_0(struct ibv_pd_1_0 *pd,
953 struct ibv_ah_attr *attr)
954 {
955 struct ibv_ah *real_ah;
956 struct ibv_ah_1_0 *ah;
957
958 ah = malloc(sizeof *ah);
959 if (!ah)
960 return NULL;
961
962 real_ah = ibv_create_ah(pd->real_pd, attr);
963 if (!real_ah) {
964 free(ah);
965 return NULL;
966 }
967
968 ah->context = pd->context;
969 ah->pd = pd;
970 ah->real_ah = real_ah;
971
972 return ah;
973 }
974 symver(__ibv_create_ah_1_0, ibv_create_ah, IBVERBS_1.0);
975
__ibv_destroy_ah_1_0(struct ibv_ah_1_0 * ah)976 int __ibv_destroy_ah_1_0(struct ibv_ah_1_0 *ah)
977 {
978 int ret;
979
980 ret = ibv_destroy_ah(ah->real_ah);
981 if (ret)
982 return ret;
983
984 free(ah);
985 return 0;
986 }
987 symver(__ibv_destroy_ah_1_0, ibv_destroy_ah, IBVERBS_1.0);
988
__ibv_attach_mcast_1_0(struct ibv_qp_1_0 * qp,union ibv_gid * gid,uint16_t lid)989 int __ibv_attach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid)
990 {
991 return ibv_attach_mcast(qp->real_qp, gid, lid);
992 }
993 symver(__ibv_attach_mcast_1_0, ibv_attach_mcast, IBVERBS_1.0);
994
__ibv_detach_mcast_1_0(struct ibv_qp_1_0 * qp,union ibv_gid * gid,uint16_t lid)995 int __ibv_detach_mcast_1_0(struct ibv_qp_1_0 *qp, union ibv_gid *gid, uint16_t lid)
996 {
997 return ibv_detach_mcast(qp->real_qp, gid, lid);
998 }
999 symver(__ibv_detach_mcast_1_0, ibv_detach_mcast, IBVERBS_1.0);
1000
__ibv_register_driver_1_1(const char * name,ibv_driver_init_func_1_1 init_func)1001 void __ibv_register_driver_1_1(const char *name, ibv_driver_init_func_1_1 init_func)
1002 {
1003 /* The driver interface is private as of rdma-core 13. This stub is
1004 * left to preserve dynamic-link compatibility with old libfabrics
1005 * usnic providers which use this function only to suppress a fprintf
1006 * in old versions of libibverbs. */
1007 }
1008 symver(__ibv_register_driver_1_1, ibv_register_driver, IBVERBS_1.1);
1009