|
NAMEibv_get_cq_event, ibv_ack_cq_events - get and acknowledge completion queue (CQ) events SYNOPSIS#include <infiniband/verbs.h>
int ibv_get_cq_event(struct ibv_comp_channel *channel,
struct ibv_cq **cq, void **cq_context);
void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents);
DESCRIPTIONibv_get_cq_event() waits for the next completion event in the completion event channel channel. Fills the arguments cq with the CQ that got the event and cq_context with the CQ's context. ibv_ack_cq_events() acknowledges nevents events on the CQ cq. RETURN VALUEibv_get_cq_event() returns 0 on success, and -1 on error. ibv_ack_cq_events() returns no value. NOTESAll completion events that ibv_get_cq_event() returns must be acknowledged using ibv_ack_cq_events(). To avoid races, destroying a CQ will wait for all completion events to be acknowledged; this guarantees a one-to-one correspondence between acks and successful gets. Calling ibv_ack_cq_events() may be relatively expensive in the datapath, since it must take a mutex. Therefore it may be better to amortize this cost by keeping a count of the number of events needing acknowledgement and acking several completion events in one call to ibv_ack_cq_events(). EXAMPLESThe following code example demonstrates one possible way to work with completion events. It performs the following steps: Stage I: Preparation
Stage II: Completion Handling Routine
Note that an extra event may be triggered without having a corresponding completion entry in the CQ. This occurs if a completion entry is added to the CQ between Step 4 and Step 5, and the CQ is then emptied (polled) in Step 5. cq = ibv_create_cq(ctx, 1, ev_ctx, channel, 0);
if (!cq) {
/* Request notification before any completion can be created */
if (ibv_req_notify_cq(cq, 0)) {
. . . /* Wait for the completion event */
if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
/* Request notification upon the next completion event */
if (ibv_req_notify_cq(ev_cq, 0)) {
/* Empty the CQ: poll all of the completions from the CQ (if any exist) */
do {
The following code example demonstrates one possible way to work with completion events in non-blocking mode. It performs the following steps: 1. Set the completion event channel to be non-blocked
/* change the blocking mode of the completion channel */
flags = fcntl(channel->fd, F_GETFL);
rc = fcntl(channel->fd, F_SETFL, flags | O_NONBLOCK);
if (rc < 0) {
fprintf(stderr, "Failed to change file descriptor of completion event channel\n");
return 1;
}
/*
SEE ALSOibv_create_comp_channel(3), ibv_create_cq(3), ibv_req_notify_cq(3), ibv_poll_cq(3) AUTHORS
|