Gets and acknowledges completion queue (CQ) events.
#include <rdma/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);
ibv_get_cq_event() waits for the next completion event in the completion event channel channel. The argument cq is used to return the CQ that caused the event and cq_context is used to return the context of the CQ.
ibv_ack_cq_events() acknowledges nevents events on the CQ cq.
channel | struct ibv_comp_channel from ibv_create_comp_channel. |
cq | Pointer to the completion queue (CQ) associated with event. |
cq_context | User supplied context set in ibv_create_cq. |
The ibv_get_cq_event, and ibv_ack_cq_events functions return 0 on success, and -1 if the request fails.
cq = ibv_create_cq(ctx, 1, ev_ctx, channel, 0); if (!cq) { fprintf(stderr, "Failed to create CQ\n"); return 1; } /* Request notification before any completion can be created */ if (ibv_req_notify_cq(cq, 0)) { fprintf(stderr, "Couldn't request CQ notification\n"); return 1; } . . . /* Wait for the completion event */ if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) { fprintf(stderr, "Failed to get cq_event\n"); return 1; } /* Ack the event */ ibv_ack_cq_events(ev_cq, 1); /* Request notification upon the next completion event */ if (ibv_req_notify_cq(cq, 0)) { fprintf(stderr, "Couldn't request CQ notification\n"); return 1; } /* Empty the CQ: poll all of the completions from the CQ (if any exist) */ do { ne = ibv_poll_cq(cq, 1, &wc); if (ne < 0) { fprintf(stderr, "Failed to poll completions from the CQ\n"); return 1; } if (wc.status != IBV_WC_SUCCESS) { fprintf(stderr, "Completion with status 0x%x was found\n", wc.status); return 1; } } while (ne);
/* 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; } /* * poll the channel until it has an event and sleep ms_timeout * milliseconds between any iteration */ my_pollfd.fd = channel->fd; my_pollfd.events = POLLIN; my_pollfd.revents = 0; do { rc = poll(&my_polfd;, 1, ms_timeout); } while (rc == 0); if (rc < 0){ fprintf(stderr, "poll failed\n"); return 1; } ev_cq = cq; /* Wait for the completion event */ if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) { fprintf(stderr, "Failed to get cq_event\n"); return 1; } /* Ack the event */ ibv_ack_cq_events(ev_cq, 1);