ibverbs_sys/lib.rs
1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4#![allow(missing_docs)]
5// Suppress expected warnings from bindgen-generated code.
6// See https://github.com/rust-lang/rust-bindgen/issues/1651.
7#![allow(deref_nullptr)]
8include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
9
10/// An ibverb work completion.
11#[repr(C)]
12#[derive(Debug, Copy, Clone)]
13pub struct ibv_wc {
14 wr_id: u64,
15 status: ibv_wc_status::Type,
16 opcode: ibv_wc_opcode::Type,
17 vendor_err: u32,
18 byte_len: u32,
19
20 /// Immediate data OR the local RKey that was invalidated depending on `wc_flags`.
21 /// See `man ibv_poll_cq` for details.
22 pub imm_data: u32,
23 /// Local QP number of completed WR.
24 ///
25 /// Relevant for Receive Work Completions that are associated with an SRQ.
26 pub qp_num: u32,
27 /// Source QP number (remote QP number) of completed WR.
28 ///
29 /// Relevant for Receive Work Completions of a UD QP.
30 pub src_qp: u32,
31 /// Flags of the Work Completion. It is either 0 or the bitwise OR of one or more of the
32 /// following flags:
33 ///
34 /// - `IBV_WC_GRH`: Indicator that GRH is present for a Receive Work Completions of a UD QP.
35 /// If this bit is set, the first 40 bytes of the buffered that were referred to in the
36 /// Receive request will contain the GRH of the incoming message. If this bit is cleared,
37 /// the content of those first 40 bytes is undefined
38 /// - `IBV_WC_WITH_IMM`: Indicator that imm_data is valid. Relevant for Receive Work
39 /// Completions
40 pub wc_flags: ibv_wc_flags,
41 /// P_Key index (valid only for GSI QPs).
42 pub pkey_index: u16,
43 /// Source LID (the base LID that this message was sent from).
44 ///
45 /// Relevant for Receive Work Completions of a UD QP.
46 pub slid: u16,
47 /// Service Level (the SL LID that this message was sent with).
48 ///
49 /// Relevant for Receive Work Completions of a UD QP.
50 pub sl: u8,
51 /// Destination LID path bits.
52 ///
53 /// Relevant for Receive Work Completions of a UD QP (not applicable for multicast messages).
54 pub dlid_path_bits: u8,
55}
56
57#[allow(clippy::len_without_is_empty)]
58impl ibv_wc {
59 /// Returns the 64 bit value that was associated with the corresponding Work Request.
60 pub fn wr_id(&self) -> u64 {
61 self.wr_id
62 }
63
64 /// Returns the number of bytes transferred.
65 ///
66 /// Relevant if the Receive Queue for incoming Send or RDMA Write with immediate operations.
67 /// This value doesn't include the length of the immediate data, if such exists. Relevant in
68 /// the Send Queue for RDMA Read and Atomic operations.
69 ///
70 /// For the Receive Queue of a UD QP that is not associated with an SRQ or for an SRQ that is
71 /// associated with a UD QP this value equals to the payload of the message plus the 40 bytes
72 /// reserved for the GRH. The number of bytes transferred is the payload of the message plus
73 /// the 40 bytes reserved for the GRH, whether or not the GRH is present
74 pub fn len(&self) -> usize {
75 self.byte_len as usize
76 }
77
78 /// Check if this work requested completed successfully.
79 ///
80 /// A successful work completion (`IBV_WC_SUCCESS`) means that the corresponding Work Request
81 /// (and all of the unsignaled Work Requests that were posted previous to it) ended, and the
82 /// memory buffers that this Work Request refers to are ready to be (re)used.
83 pub fn is_valid(&self) -> bool {
84 self.status == ibv_wc_status::IBV_WC_SUCCESS
85 }
86
87 /// Returns the work completion status and vendor error syndrome (`vendor_err`) if the work
88 /// request did not completed successfully.
89 ///
90 /// Possible statuses include:
91 ///
92 /// - `IBV_WC_LOC_LEN_ERR`: Local Length Error: this happens if a Work Request that was posted
93 /// in a local Send Queue contains a message that is greater than the maximum message size
94 /// that is supported by the RDMA device port that should send the message or an Atomic
95 /// operation which its size is different than 8 bytes was sent. This also may happen if a
96 /// Work Request that was posted in a local Receive Queue isn't big enough for holding the
97 /// incoming message or if the incoming message size if greater the maximum message size
98 /// supported by the RDMA device port that received the message.
99 /// - `IBV_WC_LOC_QP_OP_ERR`: Local QP Operation Error: an internal QP consistency error was
100 /// detected while processing this Work Request: this happens if a Work Request that was
101 /// posted in a local Send Queue of a UD QP contains an Address Handle that is associated
102 /// with a Protection Domain to a QP which is associated with a different Protection Domain
103 /// or an opcode which isn't supported by the transport type of the QP isn't supported (for
104 /// example:
105 /// RDMA Write over a UD QP).
106 /// - `IBV_WC_LOC_EEC_OP_ERR`: Local EE Context Operation Error: an internal EE Context
107 /// consistency error was detected while processing this Work Request (unused, since its
108 /// relevant only to RD QPs or EE Context, which aren’t supported).
109 /// - `IBV_WC_LOC_PROT_ERR`: Local Protection Error: the locally posted Work Request’s buffers
110 /// in the scatter/gather list does not reference a Memory Region that is valid for the
111 /// requested operation.
112 /// - `IBV_WC_WR_FLUSH_ERR`: Work Request Flushed Error: A Work Request was in process or
113 /// outstanding when the QP transitioned into the Error State.
114 /// - `IBV_WC_MW_BIND_ERR`: Memory Window Binding Error: A failure happened when tried to bind
115 /// a MW to a MR.
116 /// - `IBV_WC_BAD_RESP_ERR`: Bad Response Error: an unexpected transport layer opcode was
117 /// returned by the responder. Relevant for RC QPs.
118 /// - `IBV_WC_LOC_ACCESS_ERR`: Local Access Error: a protection error occurred on a local data
119 /// buffer during the processing of a RDMA Write with Immediate operation sent from the
120 /// remote node. Relevant for RC QPs.
121 /// - `IBV_WC_REM_INV_REQ_ERR`: Remote Invalid Request Error: The responder detected an
122 /// invalid message on the channel. Possible causes include the operation is not supported
123 /// by this receive queue (qp_access_flags in remote QP wasn't configured to support this
124 /// operation), insufficient buffering to receive a new RDMA or Atomic Operation request, or
125 /// the length specified in a RDMA request is greater than 2^{31} bytes. Relevant for RC
126 /// QPs.
127 /// - `IBV_WC_REM_ACCESS_ERR`: Remote Access Error: a protection error occurred on a remote
128 /// data buffer to be read by an RDMA Read, written by an RDMA Write or accessed by an
129 /// atomic operation. This error is reported only on RDMA operations or atomic operations.
130 /// Relevant for RC QPs.
131 /// - `IBV_WC_REM_OP_ERR`: Remote Operation Error: the operation could not be completed
132 /// successfully by the responder. Possible causes include a responder QP related error that
133 /// prevented the responder from completing the request or a malformed WQE on the Receive
134 /// Queue. Relevant for RC QPs.
135 /// - `IBV_WC_RETRY_EXC_ERR`: Transport Retry Counter Exceeded: The local transport timeout
136 /// retry counter was exceeded while trying to send this message. This means that the remote
137 /// side didn't send any Ack or Nack. If this happens when sending the first message,
138 /// usually this mean that the connection attributes are wrong or the remote side isn't in a
139 /// state that it can respond to messages. If this happens after sending the first message,
140 /// usually it means that the remote QP isn't available anymore. Relevant for RC QPs.
141 /// - `IBV_WC_RNR_RETRY_EXC_ERR`: RNR Retry Counter Exceeded: The RNR NAK retry count was
142 /// exceeded. This usually means that the remote side didn't post any WR to its Receive
143 /// Queue. Relevant for RC QPs.
144 /// - `IBV_WC_LOC_RDD_VIOL_ERR`: Local RDD Violation Error: The RDD associated with the QP
145 /// does not match the RDD associated with the EE Context (unused, since its relevant only
146 /// to RD QPs or EE Context, which aren't supported).
147 /// - `IBV_WC_REM_INV_RD_REQ_ERR`: Remote Invalid RD Request: The responder detected an
148 /// invalid incoming RD message. Causes include a Q_Key or RDD violation (unused, since its
149 /// relevant only to RD QPs or EE Context, which aren't supported)
150 /// - `IBV_WC_REM_ABORT_ERR`: Remote Aborted Error: For UD or UC QPs associated with a SRQ,
151 /// the responder aborted the operation.
152 /// - `IBV_WC_INV_EECN_ERR`: Invalid EE Context Number: An invalid EE Context number was
153 /// detected (unused, since its relevant only to RD QPs or EE Context, which aren't
154 /// supported).
155 /// - `IBV_WC_INV_EEC_STATE_ERR`: Invalid EE Context State Error: Operation is not legal for
156 /// the specified EE Context state (unused, since its relevant only to RD QPs or EE Context,
157 /// which aren't supported).
158 /// - `IBV_WC_FATAL_ERR`: Fatal Error.
159 /// - `IBV_WC_RESP_TIMEOUT_ERR`: Response Timeout Error.
160 /// - `IBV_WC_GENERAL_ERR`: General Error: other error which isn't one of the above errors.
161 pub fn error(&self) -> Option<(ibv_wc_status::Type, u32)> {
162 match self.status {
163 ibv_wc_status::IBV_WC_SUCCESS => None,
164 status => Some((status, self.vendor_err)),
165 }
166 }
167
168 /// Returns the operation that the corresponding Work Request performed.
169 ///
170 /// This value controls the way that data was sent, the direction of the data flow and the
171 /// valid attributes in the Work Completion.
172 pub fn opcode(&self) -> ibv_wc_opcode::Type {
173 self.opcode
174 }
175
176 /// Returns a 32 bits number, in network order, in an SEND or RDMA WRITE opcodes that is being
177 /// sent along with the payload to the remote side and placed in a Receive Work Completion and
178 /// not in a remote memory buffer
179 ///
180 /// Note that IMM is only returned if `IBV_WC_WITH_IMM` is set in `wc_flags`. If this is not
181 /// the case, no immediate value was provided, and `imm_data` should be interpreted
182 /// differently. See `man ibv_poll_cq` for details.
183 pub fn imm_data(&self) -> Option<u32> {
184 if self.is_valid() && ((self.wc_flags & ibv_wc_flags::IBV_WC_WITH_IMM).0 != 0) {
185 Some(self.imm_data)
186 } else {
187 None
188 }
189 }
190}
191
192#[test]
193fn bindgen_test_layout_ibv_wc() {
194 assert_eq!(
195 ::std::mem::size_of::<ibv_wc>(),
196 48usize,
197 concat!("Size of: ", stringify!(ibv_wc))
198 );
199 assert_eq!(
200 ::std::mem::align_of::<ibv_wc>(),
201 8usize,
202 concat!("Alignment of ", stringify!(ibv_wc))
203 );
204 assert_eq!(
205 std::mem::offset_of!(ibv_wc, wr_id),
206 0usize,
207 concat!(
208 "Alignment of field: ",
209 stringify!(ibv_wc),
210 "::",
211 stringify!(wr_id)
212 )
213 );
214 assert_eq!(
215 std::mem::offset_of!(ibv_wc, status),
216 8usize,
217 concat!(
218 "Alignment of field: ",
219 stringify!(ibv_wc),
220 "::",
221 stringify!(status)
222 )
223 );
224 assert_eq!(
225 std::mem::offset_of!(ibv_wc, opcode),
226 12usize,
227 concat!(
228 "Alignment of field: ",
229 stringify!(ibv_wc),
230 "::",
231 stringify!(opcode)
232 )
233 );
234 assert_eq!(
235 std::mem::offset_of!(ibv_wc, vendor_err),
236 16usize,
237 concat!(
238 "Alignment of field: ",
239 stringify!(ibv_wc),
240 "::",
241 stringify!(vendor_err)
242 )
243 );
244 assert_eq!(
245 std::mem::offset_of!(ibv_wc, byte_len),
246 20usize,
247 concat!(
248 "Alignment of field: ",
249 stringify!(ibv_wc),
250 "::",
251 stringify!(byte_len)
252 )
253 );
254 assert_eq!(
255 std::mem::offset_of!(ibv_wc, qp_num),
256 28usize,
257 concat!(
258 "Alignment of field: ",
259 stringify!(ibv_wc),
260 "::",
261 stringify!(qp_num)
262 )
263 );
264 assert_eq!(
265 std::mem::offset_of!(ibv_wc, src_qp),
266 32usize,
267 concat!(
268 "Alignment of field: ",
269 stringify!(ibv_wc),
270 "::",
271 stringify!(src_qp)
272 )
273 );
274 assert_eq!(
275 std::mem::offset_of!(ibv_wc, wc_flags),
276 36usize,
277 concat!(
278 "Alignment of field: ",
279 stringify!(ibv_wc),
280 "::",
281 stringify!(wc_flags)
282 )
283 );
284 assert_eq!(
285 std::mem::offset_of!(ibv_wc, pkey_index),
286 40usize,
287 concat!(
288 "Alignment of field: ",
289 stringify!(ibv_wc),
290 "::",
291 stringify!(pkey_index)
292 )
293 );
294 assert_eq!(
295 std::mem::offset_of!(ibv_wc, slid),
296 42usize,
297 concat!(
298 "Alignment of field: ",
299 stringify!(ibv_wc),
300 "::",
301 stringify!(slid)
302 )
303 );
304 assert_eq!(
305 std::mem::offset_of!(ibv_wc, sl),
306 44usize,
307 concat!(
308 "Alignment of field: ",
309 stringify!(ibv_wc),
310 "::",
311 stringify!(sl)
312 )
313 );
314 assert_eq!(
315 std::mem::offset_of!(ibv_wc, dlid_path_bits),
316 45usize,
317 concat!(
318 "Alignment of field: ",
319 stringify!(ibv_wc),
320 "::",
321 stringify!(dlid_path_bits)
322 )
323 );
324}
325
326impl Default for ibv_wc {
327 fn default() -> Self {
328 ibv_wc {
329 wr_id: 0,
330 status: ibv_wc_status::IBV_WC_GENERAL_ERR,
331 opcode: ibv_wc_opcode::IBV_WC_LOCAL_INV,
332 vendor_err: 0,
333 byte_len: 0,
334 imm_data: 0,
335 qp_num: 0,
336 src_qp: 0,
337 wc_flags: ibv_wc_flags(0),
338 pkey_index: 0,
339 slid: 0,
340 sl: 0,
341 dlid_path_bits: 0,
342 }
343 }
344}