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