24 struct ibv_comp_channel *channel,
bool useownchannel) :
36 EOUT(
"Completion channel not specified ???");
42 EOUT(
"Couldn't allocate completion queue (CQ)");
48 ibv_req_notify_cq(
f_cq, 0);
56 if (ibv_destroy_cq(f_cq))
57 EOUT(
"Fail to destroy CQ");
62 ibv_destroy_comp_channel(f_channel);
72 int ne = ibv_poll_cq(cq(), 1, &f_wc);
77 EOUT(
"ibv_poll_cq error");
81 if (f_wc.status != IBV_WC_SUCCESS) {
82 EOUT(
"Completion error=%d %s wr_id=%llu syndrom 0x%x qpnum=%x src_qp=%x",
83 f_wc.status, GetStrError(f_wc.status), f_wc.wr_id,
84 f_wc.vendor_err, f_wc.qp_num, f_wc.src_qp);
95 if ((res!=0) || (timeout<=0.) || (f_channel==0))
return res;
101 bool is_event(
false);
103 while (now < finish) {
105 if (now < fastfinish) {
108 if (res!=0)
return res;
111 int timeout_ms = lrint((finish-now)*1000);
113 if (timeout_ms<0) {
EOUT(
"Negative timeout!!!"); timeout_ms = 0; }
122 ufds.fd = f_channel->fd;
123 ufds.events = POLLIN;
126 int status = poll(&ufds, 1, timeout_ms);
128 if (status==0)
return Poll();
130 if (status>0) { is_event =
true;
break; }
132 if ((status==-1) && (errno != EINTR)) {
133 EOUT(
"Error when waiting IB event");
169 if (!is_event)
return Poll();
171 struct ibv_cq *ev_cq;
173 if (ibv_get_cq_event(f_channel, &ev_cq, (
void**)&ev_ctx)) {
174 EOUT(
"Failed to get cq_event");
178 if ((ev_ctx==0) || (ev_ctx->
own_cq != ev_cq)) {
179 EOUT(
"Error with getting context after ibv_get_cq_event");
191 if (ibv_req_notify_cq(ev_cq, 0)) {
192 EOUT(
"Couldn't request CQ notification");
201 if (fCQContext.events_get > 0) {
202 ibv_ack_cq_events(f_cq, fCQContext.events_get);
203 fCQContext.events_get = 0;
214 static discr_t errors[] = {
215 { code:IBV_WC_LOC_LEN_ERR, name:
"IBV_WC_LOC_LEN_ERR" },
216 { code:IBV_WC_LOC_QP_OP_ERR, name:
"IBV_WC_LOC_QP_OP_ERR" },
217 { code:IBV_WC_LOC_EEC_OP_ERR, name:
"IBV_WC_LOC_EEC_OP_ERR" },
218 { code:IBV_WC_LOC_PROT_ERR, name:
"IBV_WC_LOC_PROT_ERR" },
219 { code:IBV_WC_WR_FLUSH_ERR, name:
"IBV_WC_WR_FLUSH_ERR" },
220 { code:IBV_WC_MW_BIND_ERR, name:
"IBV_WC_MW_BIND_ERR" },
221 { code:IBV_WC_BAD_RESP_ERR, name:
"IBV_WC_BAD_RESP_ERR" },
222 { code:IBV_WC_LOC_ACCESS_ERR, name:
"IBV_WC_LOC_ACCESS_ERR" },
223 { code:IBV_WC_REM_INV_REQ_ERR, name:
"IBV_WC_REM_INV_REQ_ERR" },
224 { code:IBV_WC_REM_ACCESS_ERR, name:
"IBV_WC_REM_ACCESS_ERR" },
225 { code:IBV_WC_REM_OP_ERR, name:
"IBV_WC_REM_OP_ERR" },
226 { code:IBV_WC_RETRY_EXC_ERR, name:
"IBV_WC_RETRY_EXC_ERR" },
227 { code:IBV_WC_RNR_RETRY_EXC_ERR, name:
"IBV_WC_RNR_RETRY_EXC_ERR" },
228 { code:IBV_WC_LOC_RDD_VIOL_ERR, name:
"IBV_WC_LOC_RDD_VIOL_ERR" },
229 { code:IBV_WC_REM_INV_RD_REQ_ERR, name:
"IBV_WC_REM_INV_RD_REQ_ERR" },
230 { code:IBV_WC_REM_ABORT_ERR, name:
"IBV_WC_REM_ABORT_ERR" },
231 { code:IBV_WC_INV_EECN_ERR, name:
"IBV_WC_INV_EECN_ERR" },
232 { code:IBV_WC_INV_EEC_STATE_ERR, name:
"IBV_WC_INV_EEC_STATE_ERR" },
233 { code:IBV_WC_FATAL_ERR, name:
"IBV_WC_FATAL_ERR" },
234 { code:IBV_WC_RESP_TIMEOUT_ERR, name:
"IBV_WC_RESP_TIMEOUT_ERR" },
235 { code:IBV_WC_GENERAL_ERR, name:
"IBV_WC_GENERAL_ERR" },
239 for (
const discr_t* d = errors; d->name!=0; d++) {
240 if (err==d->code)
return d->name;
ComplQueueContext fCQContext
ComplQueue(ContextRef ctx, int size, struct ibv_comp_channel *channel, bool use_own_channel=false)
int Wait(double timeout, double fasttm=0.)
struct ibv_comp_channel * f_channel
static const char * GetStrError(int err)
Reference to verbs::Context
struct ibv_context * context() const
Class for acquiring and holding timestamps.
Context object for completion queue operations.