HIDDEN int ibverbs_init(struct ibv_device ***list) { const char *sysfs_path; struct ibv_sysfs_dev *sysfs_dev, *next_dev; struct ibv_device *device; int num_devices = 0; int list_size = 0; int statically_linked = 0; int no_driver = 0; int ret; *list = NULL; if (getenv("RDMAV_FORK_SAFE") || getenv("IBV_FORK_SAFE")) if (ibv_fork_init()) fprintf(stderr, PFX "Warning: fork()-safety requested " "but init failed\n"); sysfs_path = ibv_get_sysfs_path(); if (!sysfs_path) return -ENOSYS; ret = check_abi_version(sysfs_path); if (ret) return -ret; check_memlock_limit(); read_config(); ret = vib_find_sysfs_devs(); if (ret) return -ret; for (sysfs_dev = sysfs_dev_list; sysfs_dev; sysfs_dev = sysfs_dev->next) { device = try_drivers(sysfs_dev); if (device) { add_device(device, list, &num_devices, &list_size); sysfs_dev->have_driver = 1; } else no_driver = 1; } if (!no_driver) goto out; /* * Check if we can dlopen() ourselves. If this fails, * libibverbs is probably statically linked into the * executable, and we should just give up, since trying to * dlopen() a driver module will fail spectacularly (loading a * driver .so will bring in dynamic copies of libibverbs and * libdl to go along with the static copies the executable * has, which quickly leads to a crash. */ { void *hand = dlopen(NULL, RTLD_NOW); if (!hand) { fprintf(stderr, PFX "Warning: dlopen(NULL) failed, " "assuming static linking.\n"); statically_linked = 1; goto out; } dlclose(hand); } load_drivers(); for (sysfs_dev = sysfs_dev_list; sysfs_dev; sysfs_dev = sysfs_dev->next) { if (sysfs_dev->have_driver) continue; device = try_drivers(sysfs_dev); if (device) { add_device(device, list, &num_devices, &list_size); sysfs_dev->have_driver = 1; } } out: for (sysfs_dev = sysfs_dev_list, next_dev = sysfs_dev ? sysfs_dev->next : NULL; sysfs_dev; sysfs_dev = next_dev, next_dev = sysfs_dev ? sysfs_dev->next : NULL) { if (!sysfs_dev->have_driver) { fprintf(stderr, PFX "Warning: no userspace device-specific " "driver found for %s\n", sysfs_dev->sysfs_path); if (statically_linked) fprintf(stderr, " When linking libibverbs statically, " "driver must be statically linked too.\n"); } free(sysfs_dev); } return num_devices; }
static int ucma_init(void) { struct ibv_device **dev_list = NULL; struct cma_device *cma_dev; struct ibv_device_attr attr; int i, ret, dev_cnt; pthread_mutex_lock(&mut); if (cma_dev_cnt) { pthread_mutex_unlock(&mut); return 0; } ret = check_abi_version(); if (ret) goto err1; dev_list = ibv_get_device_list(&dev_cnt); if (!dev_list) { printf("CMA: unable to get RDMA device list\n"); ret = ERR(ENODEV); goto err1; } cma_dev_array = malloc(sizeof *cma_dev * dev_cnt); if (!cma_dev_array) { ret = ERR(ENOMEM); goto err2; } for (i = 0; dev_list[i];) { cma_dev = &cma_dev_array[i]; cma_dev->guid = ibv_get_device_guid(dev_list[i]); cma_dev->verbs = ibv_open_device(dev_list[i]); if (!cma_dev->verbs) { printf("CMA: unable to open RDMA device\n"); ret = ERR(ENODEV); goto err3; } i++; ret = ibv_query_device(cma_dev->verbs, &attr); if (ret) { printf("CMA: unable to query RDMA device\n"); goto err3; } cma_dev->port_cnt = attr.phys_port_cnt; cma_dev->max_initiator_depth = (uint8_t) attr.max_qp_init_rd_atom; cma_dev->max_responder_resources = (uint8_t) attr.max_qp_rd_atom; } cma_dev_cnt = dev_cnt; pthread_mutex_unlock(&mut); ibv_free_device_list(dev_list); return 0; err3: while (i--) ibv_close_device(cma_dev_array[i].verbs); free(cma_dev_array); err2: ibv_free_device_list(dev_list); err1: pthread_mutex_unlock(&mut); return ret; }