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