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
16 void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents);
17
18
20 ibv_get_cq_event() waits for the next completion event in the comple‐
21 tion event channel channel. Fills the arguments cq with the CQ that
22 got the event and cq_context with the CQ's context.
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(ev_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 /* there may be an extra event with no completion in the CQ */
102 if (ne == 0)
103 continue;
104
105 if (wc.status != IBV_WC_SUCCESS) {
106 fprintf(stderr, "Completion with status 0x%x was found\n", wc.status);
107 return 1;
108 }
109 } while (ne);
110
111 The following code example demonstrates one possible way to work with
112 completion events in non-blocking mode. It performs the following
113 steps:
114
115 1. Set the completion event channel to be non-blocked
116 2. Poll the channel until there it has a completion event
117 3. Get the completion event and ack it
118
119 /* change the blocking mode of the completion channel */
120 flags = fcntl(channel->fd, F_GETFL);
121 rc = fcntl(channel->fd, F_SETFL, flags | O_NONBLOCK);
122 if (rc < 0) {
123 fprintf(stderr, "Failed to change file descriptor of completion event channel\n");
124 return 1;
125 }
126
127
128 /*
129 * poll the channel until it has an event and sleep ms_timeout
130 * milliseconds between any iteration
131 */
132 my_pollfd.fd = channel->fd;
133 my_pollfd.events = POLLIN;
134 my_pollfd.revents = 0;
135
136 do {
137 rc = poll(&my_pollfd, 1, ms_timeout);
138 } while (rc == 0);
139 if (rc < 0) {
140 fprintf(stderr, "poll failed\n");
141 return 1;
142 }
143 ev_cq = cq;
144
145 /* Wait for the completion event */
146 if (ibv_get_cq_event(channel, &ev_cq, &ev_ctx)) {
147 fprintf(stderr, "Failed to get cq_event\n");
148 return 1;
149 }
150
151 /* Ack the event */
152 ibv_ack_cq_events(ev_cq, 1);
153
154
156 ibv_create_comp_channel(3), ibv_create_cq(3), ibv_req_notify_cq(3),
157 ibv_poll_cq(3)
158
159
161 Dotan Barak
162 <dotanba@gmail.com>
163
164
165
166libibverbs 2006-10-31 IBV_GET_CQ_EVENT(3)