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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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