RDMA_CM(7)
π RDMA_CM π
okay bestie, gather round, because we're about to talk about the rdma_cm β aka the RDMA communication manager, straight outta the Librdmacm Programmer's Manual. yes this is a real manpage, yes it's a lot, yes we're doing it together. no cap. π«Ά
β¨ NAME β¨
rdma_cm β RDMA communication manager. that's the whole name. short, sweet, iconic. π
β¨ SYNOPSIS β¨
#include <rdma/rdma_cma.h>
literally one include and you're in. π
β¨ DESCRIPTION β¨
it's used to establish communication over RDMA transports. that's it, that's the description. the manpage said it in one line and honestly? ate. π₯
β¨ NOTES β¨
so the RDMA CM is a communication manager, and its whole job is setting up reliable, connected and unreliable datagram data transfers. it gives you an RDMA transport neutral interface for establishing connections, which is a fancy way of saying "you don't have to care which transport, we got you."
the API concepts are based on sockets β yes, like your fave socket() energy β but they've been adapted for queue pair (QP) based semantics. what does that mean? two things:
- communication must be over a specific RDMA device, and
- data transfers are message based.
the RDMA CM can control both the QP and the communication management (that's connection setup / teardown) portions of an RDMA API β or it can do only the communication management piece. either way, it works in conjunction with the verbs API defined by the libibverbs library, because libibverbs is the one providing the underlying interfaces needed to actually send and receive data. it's giving collab. π€
now, the RDMA CM can operate asynchronously or synchronously, and you control which mode via the rdma_cm event channel parameter in specific calls:
- if you provide an event channel, an
rdma_cmidentifier will report its event data (results of connecting, for example) on that channel. β¨ - if you don't provide a channel, then all
rdma_cmoperations for the selectedrdma_cmidentifier will block until they complete. so like, know what you're signing up for. π
and finally, the RDMA CM gives an option to different libibverbs providers to advertise and use various QP configuration options that are specific to that provider. this functionality is called ECE (enhanced connection establishment). iykyk. π
β¨ RDMA VERBS β¨
the rdma_cm supports the full range of verbs available through the libibverbs library and interfaces. but wait β it also provides wrapper functions for some of the more commonly used verbs funcationality. (that's a typo in the original and we're keeping it, character for character, because accuracy is the vibe. π)
the full set of abstracted verb calls is:
rdma_reg_msgsβ register an array of buffers for sending and receivingrdma_reg_readβ registers a buffer for RDMA read operationsrdma_reg_writeβ registers a buffer for RDMA write operationsrdma_dereg_mrβ deregisters a memory regionrdma_post_recvβ post a buffer to receive a messagerdma_post_sendβ post a buffer to send a messagerdma_post_readβ post an RDMA to read data into a bufferrdma_post_writeβ post an RDMA to send data from a bufferrdma_post_recvvβ post a vector of buffers to receive a messagerdma_post_sendvβ post a vector of buffers to send a messagerdma_post_readvβ post a vector of buffers to receive an RDMA readrdma_post_writevβ post a vector of buffers to send an RDMA writerdma_post_ud_sendβ post a buffer to send a message on a UD QPrdma_get_send_compβ get completion status for a send or RDMA operationrdma_get_recv_compβ get information about a completed receive
slay. that's fifteen wrappers, all accounted for, none skipped. π
πΈ CLIENT OPERATION πΈ
this section is the general overview of the basic operation for the active, or client, side of communication. bestie listen β this flow assumes asynchronous operation with low level call details shown. if you want synchronous operation, then calls to rdma_create_event_channel, rdma_get_cm_event, rdma_ack_cm_event, and rdma_destroy_event_channel would be eliminated. gone. not invited to the party. π
also, abstracted calls β such as rdma_create_ep β encapsulate several of these calls under a single API. and you can always go peek at the example applications for code samples. π
a general connection flow would be:
rdma_getaddrinfoβ retrieve address information of the destinationrdma_create_event_channelβ create channel to receive eventsrdma_create_idβ allocate anrdma_cm_id, this is conceptually similar to a socketrdma_resolve_addrβ obtain a local RDMA device to reach the remote addressrdma_get_cm_eventβ wait forRDMA_CM_EVENT_ADDR_RESOLVEDeventrdma_ack_cm_eventβ ack eventrdma_create_qpβ allocate a QP for the communicationrdma_resolve_routeβ determine the route to the remote addressrdma_get_cm_eventβ wait forRDMA_CM_EVENT_ROUTE_RESOLVEDeventrdma_ack_cm_eventβ ack eventrdma_connectβ connect to the remote serverrdma_get_cm_eventβ wait forRDMA_CM_EVENT_ESTABLISHEDeventrdma_ack_cm_eventβ ack event- Perform data transfers over connection
rdma_disconnectβ tear-down connectionrdma_get_cm_eventβ wait forRDMA_CM_EVENT_DISCONNECTEDeventrdma_ack_cm_eventβ ack eventrdma_destroy_qpβ destroy the QPrdma_destroy_idβ release therdma_cm_idrdma_destroy_event_channelβ release the event channelrdma_freeaddrinfoβ release the list ofrdma_addrinfostructuresrdma_set_local_eceβ set desired ECE options
an almost identical process is used to setup unreliable datagram (UD) communication between nodes. however, no actual connection is formed between QPs, so disconnection is not needed. (no connection, no breakup text. iconic.) π
although this example shows the client initiating the disconnect, either side of a connection may initiate the disconnect. periodt.
πΈ SERVER OPERATION πΈ
and now for the passive, or server, side of communication. same energy, different vibes. a general connection flow would be:
rdma_create_event_channelβ create channel to receive eventsrdma_create_idβ allocate anrdma_cm_id, this is conceptually similar to a socketrdma_bind_addrβ set the local port number to listen onrdma_listenβ begin listening for connection requestsrdma_get_cm_eventβ wait forRDMA_CM_EVENT_CONNECT_REQUESTevent with a newrdma_cm_idrdma_create_qpβ allocate a QP for the communication on the newrdma_cm_idrdma_acceptβ accept the connection requestrdma_ack_cm_eventβ ack eventrdma_get_cm_eventβ wait forRDMA_CM_EVENT_ESTABLISHEDeventrdma_ack_cm_eventβ ack event- Perform data transfers over connection
rdma_get_cm_eventβ wait forRDMA_CM_EVENT_DISCONNECTEDeventrdma_ack_cm_eventβ ack eventrdma_disconnectβ tear-down connectionrdma_destroy_qpβ destroy the QPrdma_destroy_idβ release the connectedrdma_cm_idrdma_destroy_idβ release the listeningrdma_cm_idrdma_destroy_event_channelβ release the event channelrdma_get_remote_eceβ get ECe options sent by the clientrdma_set_local_eceβ set desired ECE options
yes, rdma_destroy_id shows up twice, and no, that's not a glitch β you're releasing two different ids, bestie. one connected, one listening. two icons, two farewells. π
β RETURN CODES β
= 0 success
= -1 error - see errno for more details
most librdmacm functions return 0 to indicate success, and a -1 return value to indicate failure.
if a function operates asynchronously, a return value of 0 means the operation was successfully started. but heads up β the operation could still complete in error. users should check the status of the related event. do not skip the vibe check on your events, fr fr. π«Ά
if the return value is -1, then errno will contain additional information regarding the reason for the failure.
β οΈ okay this next part is important and slightly cursed. prior versions of the library would return-errnoand not seterrnofor some cases related toENOMEM,ENODEV,ENODATA,EINVAL, andEADDRNOTAVAILcodes. applications that want to check these codes and have compatibility with prior library versions must manually seterrnoto the negative of the return code if it is< -1. so if you're dealing with old code, that's the homework. good luck babe. π
π SEE ALSO π
the whole friend group, all of them, no one left out:
rdma_accept(3),rdma_ack_cm_event(3),rdma_bind_addr(3),rdma_connect(3),rdma_create_ep(3),rdma_create_event_channel(3),rdma_create_id(3),rdma_create_qp(3),rdma_dereg_mr(3),rdma_destroy_ep(3),rdma_destroy_event_channel(3),rdma_destroy_id(3),rdma_destroy_qp(3),rdma_disconnect(3),rdma_event_str(3),rdma_free_devices(3),rdma_freeaddrinfo(3),rdma_getaddrinfo(3),rdma_get_cm_event(3),rdma_get_devices(3),rdma_get_dst_port(3),rdma_get_local_addr(3),rdma_get_peer_addr(3),rdma_get_recv_comp(3),rdma_get_remote_ece(3),rdma_get_request(3),rdma_get_send_comp(3),rdma_get_src_port(3),rdma_join_multicast(3),rdma_leave_multicast(3),rdma_listen(3),rdma_migrate_id(3),rdma_notify(3),rdma_post_read(3)rdma_post_readv(3),rdma_post_recv(3),rdma_post_recvv(3),rdma_post_send(3),rdma_post_sendv(3),rdma_post_ud_send(3),rdma_post_write(3),rdma_post_writev(3),rdma_query_addrinfo(3),rdma_reg_msgs(3),rdma_reg_read(3),rdma_reg_write(3),rdma_reject(3),rdma_resolve_addr(3),rdma_resolve_addrinfo(3),rdma_resolve_route(3),rdma_get_remote_ece(3),rdma_set_option(3),rdma_write_cm_event(3),mckey(1),rdma_client(1),rdma_server(1),rping(1),ucmatose(1),udaddy(1)
(yes, rdma_get_remote_ece(3) is in there twice. it's just that popular. and yes, rdma_post_read(3) is missing its comma in the original β we kept it exactly as-is because that's the whole point. π)
and that's the whole page, bestie!! πβ¨ this one came from librdmacm, dated 2010-07-19 β vintage but still serving. go forth and resolve some routes. you got this. ππ¦πΈ
π¦ where this page comes from
- alpine 3.24: rdma-core-doc 61.0-r0 Β· GPL-2.0-only OR BSD-2-Clause
- arch rolling: rdma-core 65.0-1 Β· GPL-2.0-or-later OR LicenseRef-OpenIB.org-BSD-MIT AND GPL-2.0-or-later OR LicenseRef-OpenIB.org-BSD-FreeBSD AND GPL-2.0-or-later OR LicenseRef-Intel-BSD-3-Clause AND GPL-2.0-or-later OR LicenseRef-PathScale-BSD-Patent-License AND CC0-1.0 AND MIT AND BSD-2-Clause AND CPL-1.0 OR BSD-2-Clause OR GPL-2.0-or-later
- centos-stream 10: rdma-core-devel 62.0-3.el10 Β· GPLv2 or BSD
- centos-stream 9: rdma-core-devel 61.0-3.el9 Β· GPLv2 or BSD
- centos-stream 9: rdma-core-devel 61.0-3.el9 Β· GPLv2 or BSD
- fedora 44: rdma-core-devel 61.0-2.fc44 Β· GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
- fedora 44: rdma-core-devel 61.0-2.fc44 Β· GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
- fedora 44: rdma-core-devel 61.1^20260812git975bdaf-1.fc44 Β· GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
- fedora 44: rdma-core-devel 61.1^20260812git975bdaf-1.fc44 Β· GPL-2.0-only OR BSD-2-Clause AND BSD-3-Clause
- nixos 26.05: rdma-core 62.0
- nixpkgs unstable: rdma-core 65.0
- ubuntu resolute: librdmacm-dev 61.0-2ubuntu3 Β· BSD-MIT OR GPL-2.0-only
- ubuntu stonking: librdmacm-dev 64.0-1ubuntu1 Β· BSD-MIT OR GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms