ibv_get_async_event, ibv_ack_async_event

Gets or acknowledges the asynchronous events.

Syntax

#include <rdma/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

The ibv_get_async_event() function waits for the next async event of the remote direct memory access (RDMA) device context and returns it through theevent pointer, which is an ibv_async_event struct, as defined in the <rdma/verbs.h> file.

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(Not Supported)*/
                int		port_num;					/* port number that got the event */
        } element;
        enum ibv_event_type     event_type;     /* type of the event */
};

The ibv_create_qp() function updates the qp_init_attr parameter in the cap struct with the actual QP values of the QP that was created. The values are greater than or equal to the values requested. The ibv_destroy_qp() function destroys the QP by using the qp parameter.

One member of the element union is valid, depending on the event_type member of the structure. The event_type member can be one of the following events:
Item Descriptor
QP events  
IBV_EVENT_QP_FATAL Error occurred on a QP and it transitions to error state.
IBV_EVENT_QP_REQ_ERR Invalid request that causes a local work queue error.
IBV_EVENT_QP_ACCESS_ERR Local access violation error.
IBV_EVENT_COMM_EST Communication is established on a QP.
IBV_EVENT_SQ_DRAINED Send queue is drained of outstanding messages in progress.
IBV_EVENT_PATH_MIG A connection is moved to an alternative path.
IBV_EVENT_PATH_MIG_ERR A connection failed to moved to the alternative path.
CQ events  
IBV_EVENT_CQ_ERR CQ is in error (CQ overrun).
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 Link ID (LID) is changed on a port.
IBV_EVENT_PKEY_CHANGE The P_Key table is changed on a port.
CA events  
IBV_EVENT_DEVICE_FATAL CA is in FATAL state.

The ibv_ack_async_event() function acknowledges the asynchronous event.

Notes:
  • All asynchronous events that the ibv_get_async_event() function returns must be acknowledged by using the ibv_ack_async_event() event. To avoid competition, destroying an object (CQ or QP) waits for all affiliated events for the object to be acknowledged. This process avoids an application from retrieving an affiliated event after the corresponding object is destroyed.
  • The ibv_get_async_event() function is a blocking function. If multiple threads call this function simultaneously, then when an async event occurs, only one thread will receive this function. It is not possible to predict the thread that receives the function.

Input Data

Item Descriptor
struct ibv_context *context The ibv_context struct for the ibv_open_device function.
struct ibv_async_event *event The event pointer.

Return Value

The ibv_get_async_event() function returns 0 on success, and -1 if the request fails.

The ibv_ack_async_event() function returns no value.

Example

The following code example demonstrates one possible way to work with async events in nonblocking mode. The event executes the following steps:
  1. Sets the async events queue in the nonblocked work mode.
  2. Polls the queue until it has an asynchronous event.
  3. Gets the asynchronous event and acknowledges it.
/* 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 &lt; 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);