IBV_GET_ASYNC_EVENT(3)
π ibv_get_async_event, ibv_ack_async_event β bestie's guide to grabbing & acking async events π
okay so β¨ welcome to the Libibverbs Programmer's Manual, the corner of the docs where we talk about RDMA async events and honestly? it's giving main character energy. two functions, one vibe: ibv_get_async_event grabs an event, ibv_ack_async_event says "heard, ty bestie, we're done here." π
β¨ NAME β¨
ibv_get_async_event, ibv_ack_async_event β get or acknowledge asynchronous events π¦
πΈ SYNOPSIS πΈ
#include <infiniband/verbs.h>
int ibv_get_async_event(struct ibv_context *context,
struct ibv_async_event *event);
void ibv_ack_async_event(struct ibv_async_event *event);
π DESCRIPTION π
ibv_get_async_event() waits for the next async event of the RDMA device context context, and hands it back through the pointer event. That event is an ibv_async_event struct, and it's defined right there in <infiniband/verbs.h> β no cap, go look:
struct ibv_async_event {
union {
struct ibv_cq *cq; /* CQ that got the event */
struct ibv_qp *qp; /* QP that got the event */
struct ibv_srq *srq; /* SRQ that got the event */
struct ibv_wq *wq; /* WQ that got the event */
int port_num; /* port number that got the event */
} element;
enum ibv_event_type event_type; /* type of the event */
};
here's the tea β: only one member of that element union is actually valid at a time, and which one it is depends on the event_type member of the struct. so like, check event_type first, then go touch the union. iykyk.
event_type is gonna be one of the following events, and yes we're listing them ALL because they're all iconic in their own way:
π QP events
IBV_EVENT_QP_FATALβ bestieβ¦ an error occurred on a QP and it transitioned to error state πIBV_EVENT_QP_REQ_ERRβ Invalid Request Local Work Queue ErrorIBV_EVENT_QP_ACCESS_ERRβ Local access violation error πIBV_EVENT_COMM_ESTβ Communication was established on a QP β¨ (good news era)IBV_EVENT_SQ_DRAINEDβ the Send Queue was drained of outstanding messages in progressIBV_EVENT_PATH_MIGβ a connection has migrated to the alternate path πIBV_EVENT_PATH_MIG_ERRβ a connection failed to migrate to the alternate path πIBV_EVENT_QP_LAST_WQE_REACHEDβ Last WQE Reached on a QP associated with an SRQ
π CQ events
IBV_EVENT_CQ_ERRβ CQ is in error (CQ overrun) π
πΈ SRQ events
IBV_EVENT_SRQ_ERRβ an error occurred on an SRQ πIBV_EVENT_SRQ_LIMIT_REACHEDβ the SRQ limit was reached
π§ WQ events
IBV_EVENT_WQ_FATALβ an error occurred on a WQ and it transitioned to error state
β Port events
IBV_EVENT_PORT_ACTIVEβ Link became active on a port π₯IBV_EVENT_PORT_ERRβ Link became unavailable on a port πIBV_EVENT_LID_CHANGEβ LID was changed on a portIBV_EVENT_PKEY_CHANGEβ P_Key table was changed on a portIBV_EVENT_SM_CHANGEβ SM was changed on a portIBV_EVENT_CLIENT_REREGISTERβ SM sent a CLIENT_REREGISTER request to a portIBV_EVENT_GID_CHANGEβ GID table was changed on a port
π«Ά CA events
IBV_EVENT_DEVICE_FATALβ CA is in FATAL state πIBV_EVENT_DEVICE_SPEED_CHANGEβ speed changed on one or many ports of the device, due to configuration or state changes
and then ibv_ack_async_event() β it acknowledges the async event event. that's it, that's the whole job. queen behavior, minimal effort, maximum importance. π
π¦ RETURN VALUE π¦
ibv_get_async_event() returns 0 on success, and -1 on error.
ibv_ack_async_event() returns no value. (it simply does not participate in the return value economy π
)
π NOTES π
β οΈ listen up, this one matters: ALL async events thatibv_get_async_event()returns must be acknowledged usingibv_ack_async_event(). every single one. no skipping. no "i'll do it later." the events are watching. π
and here's why that's not just a rule for the sake of rules: to avoid races, destroying an object (CQ, SRQ or QP) will wait for all affiliated events for that object to be acknowledged. this avoids a situation where an application retrieves an affiliated event after the corresponding object has already been destroyed. so like, the destroy call is literally sitting there waiting on you to ack. don't leave it on read. π
also important: ibv_get_async_event() is a blocking function. it blocks. it waits. it's patient. so if multiple threads call this function simultaneously, then when an async event occurs, only one thread will receive it β and ngl, it is not possible to predict which thread will receive it. mystery thread. chaos thread. nobody knows. π
β¨ EXAMPLES β¨
okay so here's a code example that demonstrates one possible way to work with async events in non-blocking mode. it performs the following steps:
- Set the async events queue work mode to be non-blocked
- Poll the queue until it has an async event
- Get the async event and ack it
and here's the code, verbatim, because we do not freestyle code in this house:
/* change the blocking mode of the async event queue */
flags = fcntl(ctx->async_fd, F_GETFL);
rc = fcntl(ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
if (rc < 0) {
fprintf(stderr, "Failed to change file descriptor of async event queue\n");
return 1;
}
/*
* poll the queue until it has an event and sleep ms_timeout
* milliseconds between any iteration
*/
my_pollfd.fd = ctx->async_fd;
my_pollfd.events = POLLIN;
my_pollfd.revents = 0;
do {
rc = poll(&my_pollfd, 1, ms_timeout);
} while (rc == 0);
if (rc < 0) {
fprintf(stderr, "poll failed\n");
return 1;
}
/* Get the async event */
if (ibv_get_async_event(ctx, &async_event)) {
fprintf(stderr, "Failed to get async_event\n");
return 1;
}
/* Ack the event */
ibv_ack_async_event(&async_event);
π SEE ALSO π
π AUTHORS π
Dotan Barak <dotanba@gmail.com>
and that's the whole page bestie!! π«Ά this libibverbs manual entry is dated 2006-10-31, brought to you by libibverbs, and honestly it's been serving reliable async-event knowledge since before most of us could read. stan. β¨π π
π¦ where this page comes from
- 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
- nixos 26.05: rdma-core 62.0
- nixpkgs unstable: rdma-core 65.0
- ubuntu stonking: libibverbs-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