1IBV_GET_CQ_EVENT(3) Libibverbs Programmer's Manual IBV_GET_CQ_EVENT(3)
2
3
4
6 ibv_get_cq_event, ibv_ack_cq_events - get and acknowledge completion
7 queue (CQ) events
8
9
11 #include <infiniband/verbs.h>
12
13 int ibv_get_cq_event(struct ibv_comp_channel *channel,
14 struct ibv_cq **cq, void **cq_context);
15 void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents);
16
17
19 ibv_get_cq_event() waits for the next completion event in the comple‐
20 tion event channel channel. The argument cq is used to return the CQ
21 that caused the event and cq_context is used to return the CQ's con‐
22 text.
23
24 ibv_ack_cq_events() acknowledges nevents events on the CQ cq.
25
26
28 ibv_get_cq_event() returns 0 on success, and -1 on error.
29
30 ibv_ack_cq_events() returns no value.
31
33 All completion events that ibv_get_cq_event() returns must be acknowl‐
34 edged using ibv_ack_cq_events(). To avoid races, destroying a CQ will
35 wait for all completion events to be acknowledged; this guarantees a
36 one-to-one correspondence between acks and successful gets.
37
38 Calling ibv_ack_cq_events() may be relatively expensive in the data‐
39 path, since it must take a mutex. Therefore it may be better to amor‐
40 tize this cost by keeping a count of the number of events needing
41 acknowledgement and acking several completion events in one call to
42 ibv_ack_cq_events().
43
45 The following code example demonstrates one possible way to work with
46 completion events. It performs the following steps:
47
48 Stage I: Preparation
49 1. Creates a CQ
50 2. Requests for notification upon a new (first) completion event
51
52 Stage II: Completion Handling Routine
53 3. Wait for the completion event and ack it
54 4. Request for notification upon the next completion event
55 5. Empty the CQ
56
57 Note that an extra event may be triggered without having a correspond‐
58 ing completion entry in the CQ. This occurs if a completion entry is
59 added to the CQ between Step 4 and Step 5, and the CQ is then emptied
60 (polled) in Step 5.
61
62 cq = ibv_create_cq(ctx, 1, ev_ctx, channel, 0);
63 if (!cq) {
64 fprintf(stderr, "Failed to create CQ\n");
65 return 1;
66 }
67
68 /* Request notification before any completion can be created */
69 if (ibv_req_notify_cq(cq, 0)) {
70 fprintf(stderr, "Couldn't request CQ notification\n");
71 return 1;
72 }
73
74 .
75 .
76 .
77
78 /* Wait for the completion event */
79 if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
80 fprintf(stderr, "Failed to get cq_event\n");
81 return 1;
82 }
83
84 /* Ack the event */
85 ibv_ack_cq_events(ev_cq, 1);
86
87 /* Request notification upon the next completion event */
88 if (ibv_req_notify_cq(cq, 0)) {
89 fprintf(stderr, "Couldn't request CQ notification\n");
90 return 1;
91 }
92
93 /* Empty the CQ: poll all of the completions from the CQ (if any exist) */
94 do {
95 ne = ibv_poll_cq(cq, 1, &wc);
96 if (ne < 0) {
97 fprintf(stderr, "Failed to poll completions from the CQ\n");
98 return 1;
99 }
100
101 if (wc.status != IBV_WC_SUCCESS) {
102 fprintf(stderr, "Completion with status 0x%x was found\n", wc.status);
103 return 1;
104 }
105 } while (ne);
106
107 The following code example demonstrates one possible way to work with
108 completion events in non-blocking mode. It performs the following
109 steps:
110
111 1. Set the completion event channel to be non-blocked
112 2. Poll the channel until there it has a completion event
113 3. Get the completion event and ack it
114
115 /* change the blocking mode of the completion channel */
116 flags = fcntl(channel->fd, F_GETFL);
117 rc = fcntl(channel->fd, F_SETFL, flags | O_NONBLOCK);
118 if (rc < 0) {
119 fprintf(stderr, "Failed to change file descriptor of completion event channel\n");
120 return 1;
121 }
122
123
124 /*
125 * poll the channel until it has an event and sleep ms_timeout
126 * milliseconds between any iteration
127 */
128 my_pollfd.fd = channel->fd;
129 my_pollfd.events = POLLIN;
130 my_pollfd.revents = 0;
131
132 do {
133 rc = poll(&my_pollfd, 1, ms_timeout);
134 } while (rc == 0);
135 if (rc < 0) {
136 fprintf(stderr, "poll failed\n");
137 return 1;
138 }
139 ev_cq = cq;
140
141 /* Wait for the completion event */
142 if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
143 fprintf(stderr, "Failed to get cq_event\n");
144 return 1;
145 }
146
147 /* Ack the event */
148 ibv_ack_cq_events(ev_cq, 1);
149
150
152 ibv_create_comp_channel(3), ibv_create_cq(3), ibv_req_notify_cq(3),
153 ibv_poll_cq(3)
154
155
157 Dotan Barak
158 <dotanb@mellanox.co.il>
159
160
161
162libibverbs 2006-10-31 IBV_GET_CQ_EVENT(3)