fi_efa(7)
okay so bestie, welcome to fi_efa(7) from Libfabric v2.5.1 β the Amazon EFA provider manual, but actually readable π
β¨
π NAME π
fi_efa β The Amazon Elastic Fabric Adapter (EFA) Provider. Thatβs the name, thatβs the vibe, iconic.
π OVERVIEW π
The EFA provider supports the Elastic Fabric Adapter (EFA) device on Amazon EC2. EFA gives you reliable and unreliable datagram send/receive with direct hardware access from userspace, aka OS bypass. No cap, that part matters.
For reliable datagram (RDM) EP type, it supports two fabric names: efa and efa-direct. The efa fabric implements a set of wire protocols to support more capabilities and features beyond the EFA device capabilities. The efa-direct fabric, on the contrary, offloads all libfabric data plane calls to the device directly without wire protocols. Compared to the efa fabric, the efa-direct fabric supports fewer capabilities and has more mode requirements for applications. But it provides a fast path to hand off application requests to the device. To use efa-direct, set the name field in fi_fabric_attr to efa-direct. More details and difference between the two fabrics will be presented below.
β¨ SUPPORTED FEATURES β¨
π¦ Endpoint types π¦
The provider supports endpoint type FI_EP_DGRAM, and FI_EP_RDM on a new Scalable (unordered) Reliable Datagram protocol (SRD). SRD provides support for reliable datagrams and more complete error handling than typically seen with other Reliable Datagram (RD) implementations.
π RDM Endpoint capabilities π
For the efa fabric, the following data transfer interfaces are supported: FI_MSG, FI_TAGGED, FI_SEND, FI_RECV, FI_RMA, FI_WRITE, FI_READ, FI_ATOMIC, FI_DIRECTED_RECV, FI_MULTI_RECV, and FI_SOURCE. It provides SAS guarantees for data operations, and does not have a maximum message size (for all operations).
For the efa-direct fabric, it supports FI_MSG, FI_SEND, FI_RECV, FI_RMA, FI_WRITE, FI_READ, and FI_SOURCE. As mentioned earlier, it doesnβt provide SAS guarantees, and has different maximum message sizes for different operations. For MSG operations, the maximum message size is the MTU size of the efa device (approximately 8KiB). For RMA operations, the maximum message size is the maximum RDMA size of the EFA device. The exact values of these sizes can be queried by the fi_getopt API with option names FI_OPT_MAX_MSG_SIZE and FI_OPT_MAX_RMA_SIZE.
π DGRAM Endpoint capabilities π
The DGRAM endpoint only supports FI_MSG capability with a maximum message size of the MTU of the underlying hardware (approximately 8 KiB).
π§ Address vectors π§
The provider supports FI_AV_TABLE. FI_AV_MAP was deprecated in Libfabric 2.x. Applications can still use FI_AV_MAP to create an address vector. But the EFA provider implementation will print a warning and switch to FI_AV_TABLE. FI_EVENT is unsupported.
β Completion events β
The provider supports FI_CQ_FORMAT_CONTEXT, FI_CQ_FORMAT_MSG, and FI_CQ_FORMAT_DATA. FI_CQ_FORMAT_TAGGED is supported on the efa fabric of RDM endpoint.
The efa and efa-direct fabrics for RDM endpoints support FI_WAIT_UNSPEC and FI_WAIT_FD wait objects for blocking CQ operations (fi_cq_sread).
DGRAM endpoints do not support wait objects.
πΈ Modes πΈ
The provider requires the use of FI_MSG_PREFIX when running over the DGRAM endpoint. And it requires the use of FI_CONTEXT2 mode for DGRAM endpoint and the efa-direct fabric of RDM endpoint. The efa fabric of RDM endpoint doesnβt have these requirements.
π Memory registration modes π
The efa fabric of RDM endpoint does not require memory registration for send and receive operations, i.e. it does not require FI_MR_LOCAL. Applications may specify FI_MR_LOCAL in the MR mode flags in order to use descriptors provided by the application. The efa-direct fabric of FI_EP_RDM endpoint and the FI_EP_DGRAM endpoint only supports FI_MR_LOCAL.
π₯ Progress π₯
RDM and DGRAM endpoints support FI_PROGRESS_MANUAL. EFA erroneously claims the support for FI_PROGRESS_AUTO, despite not properly supporting automatic progress. Unfortunately, some Libfabric consumers also ask for FI_PROGRESS_AUTO when they only require FI_PROGRESS_MANUAL, and fixing this bug would break those applications. This will be fixed in a future version of the EFA provider by adding proper support for FI_PROGRESS_AUTO.
bestie, thatβs a real bug note: itβs claiming FI_PROGRESS_AUTO support even though it doesnβt properly support automatic progress, and fixing it right now would break apps. So itβs staying until a future version fixes it properly.
π Threading π
Both RDM and DGRAM endpoints support FI_THREAD_SAFE.
π LIMITATIONS π
π Completion events π
- DGRAM endpoints do not support synchronous CQ reads (
fi_cq_sread) or wait objects. FI_WAIT_FDis not supported for RDM endpoints with SHM transfers enabled. Valid wait objects areFI_WAIT_NONEorFI_WAIT_UNSPEC. Blocking read viafi_cq_sread()is supported and will wait on SHM completions. When SHM transfers are disabled,FI_WAIT_FDwait objects are supported.
π«Ά RMA operations π«Ά
- Completion events for RMA targets (
FI_RMA_EVENT) is not supported. - For the
efa-directfabric, the target side of RMA operation must insert the initiator sideβs address into AV before the RMA operation is kicked off, due to a current device limitation. The same limitation applies to theefafabric when theFI_OPT_EFA_HOMOGENEOUS_PEERSoption is set as true.
π¦ Zero-copy receive mode π¦
- Zero-copy receive mode can be enabled only if SHM transfer is disabled.
- Unless the application explicitly disables P2P, e.g. via
FI_HMEM_P2P_DISABLED, zero-copy receive can be enabled only if availableFI_HMEMdevices all have P2P support.
π fi_cancel support π
fi_cancelis only supported in the non-zero-copy-receive mode of theefafabric. Itβs not supported inefa-direct, DGRAM endpoint, and the zero-copy receive mode of theefafabric in RDM endpoint.
When using FI_HMEM for AWS Neuron or Habana SynapseAI buffers, the provider requires peer to peer transaction support between the EFA and the FI_HMEM device. Therefore, the FI_HMEM_P2P_DISABLED option is not supported by the EFA provider for AWS Neuron or Habana SynapseAI.
π PROVIDER SPECIFIC ENDPOINT LEVEL OPTION π
FI_OPT_EFA_RNR_RETRYβ Defines the number of RNR retry. The application can use it to reset RNR retry counter via the call tofi_setopt. Note that this option must be set before the endpoint is enabled. Otherwise, the call will fail. Also note that this option only applies to RDM endpoint.FI_OPT_EFA_EMULATED_READ,FI_OPT_EFA_EMULATED_WRITE,FI_OPT_EFA_EMULATED_ATOMICSβbool. These options only apply to thefi_getopt()call. They are used to query the EFA provider to determine if the endpoint is emulating Read, Write, and Atomic operations (return value is true), or if these operations are assisted by hardware support (return value is false).FI_OPT_EFA_USE_DEVICE_RDMAβbool. This option only applies to thefi_setopt()call. Only available if the application selects a libfabric API version >= 1.18. This option allows an application to change libfabricβs behavior with respect to RDMA transfers. Note that there is also an environment variableFI_EFA_USE_DEVICE_RDMAwhich the user may set as well. If the environment variable and the argument provided with this variable are in conflict, thenfi_setoptwill return-FI_EINVAL, and the environment variable will be respected. If the hardware does not support RDMA and the argument is true, thenfi_setoptwill return-FI_EOPNOTSUPP. If the application uses API version < 1.18, the argument is ignored andfi_setoptreturns-FI_ENOPROTOOPT. The default behavior for RDMA transfers depends on API version. For API >= 1.18 RDMA is enabled by default on any hardware which supports it. For API<1.18, RDMA is enabled by default only on certain newer hardware revisions.FI_OPT_EFA_SENDRECV_IN_ORDER_ALIGNED_128_BYTESβbool. This option only applies to thefi_setopt()call. It is used to force the endpoint to use in-order send/recv operation for each 128 bytes aligned block. Enabling the option will guarantee data inside each 128 bytes aligned block being sent and received in order, it will also guarantee data to be delivered to the receive buffer only once. If endpoint is not able to support this feature, it will return-FI_EOPNOTSUPPfor the call tofi_setopt().FI_OPT_EFA_WRITE_IN_ORDER_ALIGNED_128_BYTESβbool. This option only applies to thefi_setopt()call. It is used to set the endpoint to use in-order RDMA write operation for each 128 bytes aligned block. Enabling the option will guarantee data inside each 128 bytes aligned block being written in order, it will also guarantee data to be delivered to the target buffer only once. If endpoint is not able to support this feature, it will return-FI_EOPNOTSUPPfor the call tofi_setopt().FI_OPT_EFA_HOMOGENEOUS_PEERSβbool. This option only applies to thefi_setopt()call for RDM endpoints onefafabric. RDM endpoints onefa-directfabric are unaffected by this option. When set to true, it indicates all peers are homogeneous, meaning they run on the same platform, use the same software versions, and share identical capabilities. It accelerates the initial communication setup as interoperability between peers is guaranteed. When set to true, the target side of a RMA operation must insert the initiator sideβs address into AV before the RMA operation is kicked off, due to a current device limitation. The default value is false.FI_OPT_EFA_USE_UNSOLICITED_WRITE_RECVβbool. This option only applies to thefi_setopt()call. It is used to disable unsolicited write recv for this endpoint, which can reduce the likelihood of CQ overflow. The default value is true. Forefa-direct,FI_RX_CQ_DATAis required whenFI_OPT_EFA_USE_UNSOLICITED_WRITE_RECVis false, or it will return-FI_EOPNOTSUPPfor the call tofi_setopt().
π PROVIDER SPECIFIC DOMAIN OPS π
okay so the efa provider is out here exporting extensions for operations that the standard libfabric interface does not provide. these little extras are available via the fi_ext_efa.h header file. bestie, it's giving "bonus lore in the header" energy π
π Domain Operation Extension π
you get this domain operation extension by calling fi_open_ops (peep fi_domain(3)):
int fi_open_ops(struct fid *domain, const char *name, uint64_t flags,
void **ops, void *context);
requesting FI_EFA_DOMAIN_OPS in name returns ops as the pointer to the function table fi_efa_ops_domain, defined exactly like this:
struct fi_efa_ops_domain {
int (*query_mr)(struct fid_mr *mr, struct fi_efa_mr_attr *mr_attr);
};
πΈ query_mr πΈ
this op takes an existing memory registration as input and outputs the efa-specific mr attribute, which is defined as follows:
struct fi_efa_mr_attr {
uint16_t ic_id_validity;
uint16_t recv_ic_id;
uint16_t rdma_read_ic_id;
uint16_t rdma_recv_ic_id;
};
ic_id_validityβ validity mask of interconnect id fields. currently the following bits are supported in the mask:FI_EFA_MR_ATTR_RECV_IC_ID:recv_ic_idhas a valid value.FI_EFA_MR_ATTR_RDMA_READ_IC_ID:rdma_read_ic_idhas a valid value.FI_EFA_MR_ATTR_RDMA_RECV_IC_ID:rdma_recv_ic_idhas a valid value.
recv_ic_idβ physical interconnect used by the device to reach the MR for receive operation. it is only valid whenic_id_validityhas theFI_EFA_MR_ATTR_RECV_IC_IDbit.rdma_read_ic_idβ physical interconnect used by the device to reach the MR for RDMA read operation. it is only valid whenic_id_validityhas theFI_EFA_MR_ATTR_RDMA_READ_IC_IDbit.rdma_recv_ic_idβ physical interconnect used by the device to reach the MR for RDMA write receive. it is only valid whenic_id_validityhas theFI_EFA_MR_ATTR_RDMA_RECV_IC_IDbit.
Return value: query_mr() returns 0 on success, or the value of errno on failure (which indicates the failure reason). π
to enable GPU Direct Async (GDA), which lets the GPU interact directly with the NIC, request FI_EFA_GDA_OPS in the name parameter with efa-direct fabric. this returns ops as a pointer to the function table fi_efa_ops_gda, defined as follows:
struct fi_efa_ops_gda {
int (*query_addr)(struct fid_ep *ep_fid, fi_addr_t addr, uint16_t *ahn,
uint16_t *remote_qpn, uint32_t *remote_qkey);
int (*query_qp_wqs)(struct fid_ep *ep_fid, struct fi_efa_wq_attr *sq_attr, struct fi_efa_wq_attr *rq_attr);
int (*query_cq)(struct fid_cq *cq_fid, struct fi_efa_cq_attr *cq_attr);
int (*cq_open_ext)(struct fid_domain *domain_fid,
struct fi_cq_attr *attr,
struct fi_efa_cq_init_attr *efa_cq_init_attr,
struct fid_cq **cq_fid, void *context);
uint64_t (*get_mr_lkey)(struct fid_mr *mr);
};
β¨ query_addr β¨
this op queries the following address information for a given endpoint and destination address:
ahnβ address handle number.remote_qpnβ remote queue pair Number.remote_qkeyβ qkey for the remote queue pair.
Return value: query_addr() returns FI_SUCCESS on success, or -FI_EINVAL on failure.
π¦ query_qp_wqs π¦
this op queries EFA-specific Queue Pair work queue attributes for a given endpoint. it retrieves the send queue attributes in sq_attr and receive queue attributes in rq_attr, which is defined as follows:
struct fi_efa_wq_attr {
uint8_t *buffer;
uint32_t entry_size;
uint32_t num_entries;
uint32_t *doorbell;
uint32_t max_batch;
};
bufferβ queue buffer.entry_sizeβ size of each entry in the queue.num_entriesβ maximal number of entries in the queue.doorbellβ queue doorbell.max_batchβ maximum batch size for queue submissions.
Return value: query_qp_wqs() returns 0 on success, or the value of errno on failure (which indicates the failure reason).
π₯ query_cq π₯
this op queries EFA-specific Completion Queue attributes for a given cq:
struct fi_efa_cq_attr {
uint8_t *buffer;
uint32_t entry_size;
uint32_t num_entries;
};
bufferβ completion queue buffer.entry_sizeβ size of each completion queue entry.num_entriesβ maximal number of entries in the completion queue.
Return value: query_cq() returns 0 on success, or the value of errno on failure (which indicates the failure reason).
π cq_open_ext π
this op creates a completion queue with external memory provided via dmabuf. the memory can be passed by supplying the following struct:
struct fi_efa_cq_init_attr {
uint64_t flags;
struct {
uint8_t *buffer;
uint64_t length;
uint64_t offset;
uint32_t fd;
} ext_mem_dmabuf;
};
flagsβ a bitwise OR of the various values described below.FI_EFA_CQ_INIT_FLAGS_EXT_MEM_DMABUF: create CQ with external memory provided via dmabuf.
ext_mem_dmabufβ structure containing information about external memory when usingFI_EFA_CQ_INIT_FLAGS_EXT_MEM_DMABUFflag.bufferβ pointer to the memory mapped in the process's virtual address space. the field is optional, but if not provided, the use of CQ poll interfaces should be avoided.lengthβ length of the memory region to use.offsetβ offset within the dmabuf.fdβ file descriptor of the dmabuf.
Return value: cq_open_ext() returns 0 on success, or the value of errno on failure (which indicates the failure reason).
π get_mr_lkey π
returns the local memory translation key associated with a MR. the memory registration must have completed successfully before invoking this.
lkeyβ local memory translation key used by TX/RX buffer descriptor.
Return value: get_mr_lkey() returns lkey on success, or FI_KEY_NOTAVAIL if the registration has not completed.
π¦ Traffic Class (tclass) in EFA π¦
to prioritize the messages from a given endpoint, you can specify fi_info->tx_attr->tclass = FI_TC_LOW_LATENCY in the fi_endpoint() call to set the service level in rdma-core. all other tclass values will be ignored. periodt. π
πΈ RUNTIME PARAMETERS πΈ
FI_EFA_IFACEβ a comma-delimited list of EFA device, i.e. NIC, names that should be visible to the application. this parameter can be used to include/exclude NICs to enforce process affinity based on the hardware topology. the default value isall, which allows all available NICs to be discovered.FI_EFA_TX_SIZEβ maximum number of transmit operations before the provider returns-FI_EAGAIN. for only theRDMendpoint, this parameter will cause transmit operations to be queued when this value is set higher than the default and the transmit queue is full.FI_EFA_RX_SIZEβ maximum number of receive operations before the provider returns-FI_EAGAIN. π«Ά
π RUNTIME PARAMETERS SPECIFIC TO RDM ENDPOINT π
Okay so bestie, listen β these OFI runtime parameters apply only to the RDM endpoint. Like, RDM only, no cap. Don't come at the other endpoints with these, they're not invited to this party π
FI_EFA_RX_WINDOW_SIZEβ the max number of MTU-sized messages that can be in flight from any single endpoint as part of long message data transfer. Think of it as the group chat's message-holding capacity β¨FI_EFA_TX_QUEUE_SIZEβ how deep the transmit queue opened with the NIC goes. Careful though: this may not be set to a value greater than what the NIC supports. Respect the NIC's limits, it's literally the main character here πFI_EFA_RECVWIN_SIZEβ the size of the out of order reorder buffer (measured in messages). Messages received outside of this window will result in an error. So, like, stay in the window or it's a whole thing πFI_EFA_CQ_SIZEβ the size of any cq created, counted in number of entries.FI_EFA_MR_CACHE_ENABLEβ turns on using the mr cache and in-line registration instead of a bounce buffer for iov's larger thanmax_memcpy_size. Defaults totrue. When you disable it, it only uses a bounce buffer.FI_EFA_MR_MAX_CACHED_COUNTβ sets the max number of memory registrations that can be cached at any time.FI_EFA_MR_MAX_CACHED_SIZEβ sets the max amount of memory that cached memory registrations can hold onto at any time.FI_EFA_MAX_MEMCPY_SIZEβ the threshold size that switches between using memory copy into a pre-registered bounce buffer and memory registration on the user buffer.FI_EFA_MTU_SIZEβ overrides the default MTU size of the device. Yeah, it justβ¦ overrides it π¦FI_EFA_RX_COPY_UNEXPβ enables the use of a separate pool of bounce-buffers to copy unexpected messages out of the pre-posted receive buffers.FI_EFA_RX_COPY_OOOβ enables the use of a separate pool of bounce-buffers to copy out-of-order RTS packets out of the pre-posted receive buffers.FI_EFA_MAX_TIMEOUTβ the maximum timeout (us) for backoff to a peer after a receiver not ready error.FI_EFA_TIMEOUT_INTERVALβ the time interval (us) for the base timeout to use for exponential backoff to a peer after a receiver not ready error.FI_EFA_ENABLE_SHM_TRANSFERβ enables the SHM provider to provide the communication across all intra-node processes. Heads up: SHM transfer will be disabled in the case where ptrace protection is turned on. You can turn it off to enable shm transfer π
Okay so there's a whole lore drop here aboutFI_EFA_ENABLE_SHM_TRANSFER, and you need it fr fr:FI_EFA_ENABLE_SHM_TRANSFERis parsed during thefi_domaincall and is related to theFI_OPT_SHARED_MEMORY_PERMITTEDendpoint option. - IfFI_EFA_ENABLE_SHM_TRANSFERis set to true, theFI_OPT_SHARED_MEMORY_PERMITTEDendpoint option overridesFI_EFA_ENABLE_SHM_TRANSFER. - IfFI_EFA_ENABLE_SHM_TRANSFERis set to false, but theFI_OPT_SHARED_MEMORY_PERMITTEDis set to true, theFI_OPT_SHARED_MEMORY_PERMITTEDsetopt call will fail with-FI_EINVAL. π
FI_EFA_SHM_AV_SIZEβ defines the maximum number of entries in SHM provider's address vector.FI_EFA_SHM_MAX_MEDIUM_SIZEβ defines the switch point between small/medium message and large message. The message larger than this switch point will be transferred with large message protocol. NOTE: this parameter is now deprecated. (RIP bestie, we barely knew ye π)FI_EFA_INTER_MAX_MEDIUM_MESSAGE_SIZEβ the maximum size for inter EFA messages to be sent by using medium message protocol. Messages which can fit in one packet will be sent as eager message. Messages whose sizes are smaller than this value will be sent using medium message protocol. Other messages will be sent using CTS based long message protocol. It's giving β¨tiered routingβ¨FI_EFA_FORK_SAFEβ enablesfork()support. This may have a small performance impact and should only be set when required. Also: applications that require registering regions backed by huge pages and also require fork support are not supported. So pick a struggle, bestie π«ΆFI_EFA_RUNT_SIZEβ the maximum number of bytes that will be eagerly sent by inflight messages uses runting read message protocol (Default307200).FI_EFA_INTER_MIN_READ_MESSAGE_SIZEβ the minimum message size in bytes for inter EFA read message protocol. If instance support RDMA read, messages whose size is larger than this value will be sent by read message protocol. (Default1048576).FI_EFA_INTER_MIN_READ_WRITE_SIZEβ the mimimum message size for emulated inter EFA write to use read write protocol. If firmware support RDMA read, andFI_EFA_USE_DEVICE_RDMAis1, write requests whose size is larger than this value will use the read write protocol (Default65536). If the firmware supports RDMA write, device RDMA write will always be used. (Yes, "mimimum" β we keep the typos, they're part of the lore π)FI_EFA_USE_DEVICE_RDMAβ specify whether to require or ignore RDMA features of the EFA device. The tea β:- When set to
1/true/yes/on, all RDMA features of the EFA device are used. But if the EFA device does not support RDMA andFI_EFA_USE_DEVICE_RDMAis set to1/true/yes/on, user's application is aborted and a warning message is printed. π - When set to
0/false/no/off, libfabric will emulate allfi_rmaoperations instead of offloading them to the EFA network device. Libfabric will not use device RDMA to implement send/receive operations. - If not set, RDMA operations will occur when available based on RDMA device ID/version.
- When set to
FI_EFA_USE_HUGE_PAGEβ specify whether the EFA provider can use huge page memory for internal buffer. Using huge page memory has a small performance advantage, but can cause the system to run out of huge page memory. By default, the EFA provider will use huge page unlessFI_EFA_FORK_SAFEis set to1/on/true.FI_EFA_USE_ZCPY_RXβ enables the use of application's receive buffers in place of bounce-buffers when feasible. (Default:1). Setting this environment variable to0can disable this feature. Explicitly setting this variable to1does not guarantee this feature due to other requirements. Seehttps://github.com/ofiwg/libfabric/blob/main/prov/efa/docs/efa_rdm_protocol_v4.mdfor details. iykyk π₯FI_EFA_USE_UNSOLICITED_WRITE_RECVβ use device's unsolicited write recv functionality when it's available. (Default:1). Setting this environment variable to0can disable this feature.FI_EFA_INTERNAL_RX_REFILL_THRESHOLDβ the threshold that the EFA provider will refill the internal rx pkt pool. (Default:8). When the number of internal rx pkts to post is lower than this threshold, the refill will be skipped.FI_EFA_USE_DATA_PATH_DIRECTβ use the direct data path implementation that bypassesrdma-coreon data path, including the CQ polling and TX/RX submissions, when it's available. Setting this variable as0will disable this feature (Default:true).FI_EFA_TRACK_MRβ enable tracking of memory registrations to detect if any outstanding operations still reference an MR when it is closed. When enabled, the provider will print a warning message if an MR is closed while TX or RX operations still reference it. This is useful for debugging memory registration issues. (Default:false). Honestly kind of a slay for debugging ngl π
π SEE ALSO π
fabric(7), fi_provider(7), fi_getinfo(3) β go read these too, bestie, they're iconic π
π AUTHORS π
OpenFabrics. (Periodt. That's the whole list. Legends only β¨)
And that's the whole page, babe! π This little masterpiece is from the Libfabric Programmer's Manual, dated 2026-03-19, and it's the fi_efa(7) page. Go forth, configure your endpoints, and remember: read the defaults before you ship it ππ¦β
π¦ where this page comes from
- centos-stream 10: libfabric-devel 2.5.1-1.el10 Β· BSD-2-Clause OR GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms