mirror of
https://github.com/versity/versitygw.git
synced 2026-09-22 07:54:14 +00:00
rdma: resolve the inline-only verbs calls from the provider ops table
ibv_poll_cq, ibv_post_send, and ibv_post_recv stopped being exported library symbols in modern rdma-core: verbs.h ships them as static inline wrappers that dispatch through cq->context->ops. dlsym therefore returned null for them and the loader rejected perfectly usable libraries, failing RC server init with a bare RC_E_INTERNAL on hosts with rdma-core 61+. Open the first device briefly, read the three function pointers from its context ops table, and close it again. The check now only requires symbols that actually exist in the library, and the failure mode for an ops-less provider is explicit.
This commit is contained in:
@@ -75,7 +75,33 @@ bool IBVWrapper::ensureLoaded() {
|
||||
struct ibv_send_wr *, struct ibv_send_wr **)>(load("ibv_post_send"));
|
||||
loaded = funcs_.get_device_list != nullptr && funcs_.open_device != nullptr &&
|
||||
funcs_.alloc_pd != nullptr && funcs_.create_qp != nullptr &&
|
||||
funcs_.modify_qp != nullptr && funcs_.poll_cq != nullptr;
|
||||
funcs_.modify_qp != nullptr;
|
||||
if (loaded) {
|
||||
/* poll_cq/post_send/post_recv are static inline wrappers in
|
||||
* modern verbs.h (they dispatch through cq->context->ops), so
|
||||
* dlsym cannot find them on rdma-core 61+. Resolve them from
|
||||
* the ops table of the first successfully opened context
|
||||
* instead; every context from the same device shares these
|
||||
* providers. */
|
||||
int n = 0;
|
||||
struct ibv_device **devs = funcs_.get_device_list(&n);
|
||||
struct ibv_context *probe = nullptr;
|
||||
if (devs && n > 0) probe = funcs_.open_device(devs[0]);
|
||||
if (devs) funcs_.free_device_list(devs);
|
||||
if (!probe) {
|
||||
fprintf(stderr, "rc: no RDMA device to resolve verbs ops\n");
|
||||
loaded = false;
|
||||
} else {
|
||||
funcs_.poll_cq = probe->ops.poll_cq;
|
||||
funcs_.post_recv = probe->ops.post_recv;
|
||||
funcs_.post_send = probe->ops.post_send;
|
||||
funcs_.close_device(probe);
|
||||
if (!funcs_.poll_cq || !funcs_.post_recv || !funcs_.post_send) {
|
||||
fprintf(stderr, "rc: provider ops table incomplete\n");
|
||||
loaded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loaded) {
|
||||
/* Mirror into the member seam for direct ibv.x() calls. */
|
||||
get_device_list = funcs_.get_device_list;
|
||||
|
||||
Reference in New Issue
Block a user