rdmaxcel_sys/
lib.rs

1/*
2 * Portions Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9// sections of code adapted from https://github.com/jonhoo/rust-ibverbs
10// Copyright (c) 2016 Jon Gjengset under MIT License (MIT)
11
12mod inner {
13    #[cfg(not(cargo))]
14    use crate::ibv_wc_flags;
15    #[cfg(not(cargo))]
16    use crate::ibv_wc_opcode;
17    #[cfg(not(cargo))]
18    use crate::ibv_wc_status;
19    #[cfg(cargo)]
20    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
21
22    #[repr(C, packed(1))]
23    #[derive(Debug, Default, Clone, Copy)]
24    pub struct mlx5_wqe_ctrl_seg {
25        pub opmod_idx_opcode: u32,
26        pub qpn_ds: u32,
27        pub signature: u8,
28        pub dci_stream_channel_id: u16,
29        pub fm_ce_se: u8,
30        pub imm: u32,
31    }
32
33    #[repr(C)]
34    #[derive(Debug, Copy, Clone)]
35    pub struct ibv_wc {
36        wr_id: u64,
37        status: ibv_wc_status::Type,
38        opcode: ibv_wc_opcode::Type,
39        vendor_err: u32,
40        byte_len: u32,
41
42        /// Immediate data OR the local RKey that was invalidated depending on `wc_flags`.
43        /// See `man ibv_poll_cq` for details.
44        pub imm_data: u32,
45        /// Local QP number of completed WR.
46        ///
47        /// Relevant for Receive Work Completions that are associated with an SRQ.
48        pub qp_num: u32,
49        /// Source QP number (remote QP number) of completed WR.
50        ///
51        /// Relevant for Receive Work Completions of a UD QP.
52        pub src_qp: u32,
53        /// Flags of the Work Completion. It is either 0 or the bitwise OR of one or more of the
54        /// following flags:
55        ///
56        ///  - `IBV_WC_GRH`: Indicator that GRH is present for a Receive Work Completions of a UD QP.
57        ///    If this bit is set, the first 40 bytes of the buffered that were referred to in the
58        ///    Receive request will contain the GRH of the incoming message. If this bit is cleared,
59        ///    the content of those first 40 bytes is undefined
60        ///  - `IBV_WC_WITH_IMM`: Indicator that imm_data is valid. Relevant for Receive Work
61        ///    Completions
62        pub wc_flags: ibv_wc_flags,
63        /// P_Key index (valid only for GSI QPs).
64        pub pkey_index: u16,
65        /// Source LID (the base LID that this message was sent from).
66        ///
67        /// Relevant for Receive Work Completions of a UD QP.
68        pub slid: u16,
69        /// Service Level (the SL LID that this message was sent with).
70        ///
71        /// Relevant for Receive Work Completions of a UD QP.
72        pub sl: u8,
73        /// Destination LID path bits.
74        ///
75        /// Relevant for Receive Work Completions of a UD QP (not applicable for multicast messages).
76        pub dlid_path_bits: u8,
77    }
78
79    #[allow(clippy::len_without_is_empty)]
80    impl ibv_wc {
81        /// Returns the 64 bit value that was associated with the corresponding Work Request.
82        pub fn wr_id(&self) -> u64 {
83            self.wr_id
84        }
85
86        /// Returns the number of bytes transferred.
87        ///
88        /// Relevant if the Receive Queue for incoming Send or RDMA Write with immediate operations.
89        /// This value doesn't include the length of the immediate data, if such exists. Relevant in
90        /// the Send Queue for RDMA Read and Atomic operations.
91        ///
92        /// For the Receive Queue of a UD QP that is not associated with an SRQ or for an SRQ that is
93        /// associated with a UD QP this value equals to the payload of the message plus the 40 bytes
94        /// reserved for the GRH. The number of bytes transferred is the payload of the message plus
95        /// the 40 bytes reserved for the GRH, whether or not the GRH is present
96        pub fn len(&self) -> usize {
97            self.byte_len as usize
98        }
99
100        /// Check if this work requested completed successfully.
101        ///
102        /// A successful work completion (`IBV_WC_SUCCESS`) means that the corresponding Work Request
103        /// (and all of the unsignaled Work Requests that were posted previous to it) ended, and the
104        /// memory buffers that this Work Request refers to are ready to be (re)used.
105        pub fn is_valid(&self) -> bool {
106            self.status == ibv_wc_status::IBV_WC_SUCCESS
107        }
108
109        /// Returns the work completion status and vendor error syndrome (`vendor_err`) if the work
110        /// request did not completed successfully.
111        ///
112        /// Possible statuses include:
113        ///
114        ///  - `IBV_WC_LOC_LEN_ERR`: Local Length Error: this happens if a Work Request that was posted
115        ///    in a local Send Queue contains a message that is greater than the maximum message size
116        ///    that is supported by the RDMA device port that should send the message or an Atomic
117        ///    operation which its size is different than 8 bytes was sent. This also may happen if a
118        ///    Work Request that was posted in a local Receive Queue isn't big enough for holding the
119        ///    incoming message or if the incoming message size if greater the maximum message size
120        ///    supported by the RDMA device port that received the message.
121        ///  - `IBV_WC_LOC_QP_OP_ERR`: Local QP Operation Error: an internal QP consistency error was
122        ///    detected while processing this Work Request: this happens if a Work Request that was
123        ///    posted in a local Send Queue of a UD QP contains an Address Handle that is associated
124        ///    with a Protection Domain to a QP which is associated with a different Protection Domain
125        ///    or an opcode which isn't supported by the transport type of the QP isn't supported (for
126        ///    example:
127        ///    RDMA Write over a UD QP).
128        ///  - `IBV_WC_LOC_EEC_OP_ERR`: Local EE Context Operation Error: an internal EE Context
129        ///    consistency error was detected while processing this Work Request (unused, since its
130        ///    relevant only to RD QPs or EE Context, which aren’t supported).
131        ///  - `IBV_WC_LOC_PROT_ERR`: Local Protection Error: the locally posted Work Request’s buffers
132        ///    in the scatter/gather list does not reference a Memory Region that is valid for the
133        ///    requested operation.
134        ///  - `IBV_WC_WR_FLUSH_ERR`: Work Request Flushed Error: A Work Request was in process or
135        ///    outstanding when the QP transitioned into the Error State.
136        ///  - `IBV_WC_MW_BIND_ERR`: Memory Window Binding Error: A failure happened when tried to bind
137        ///    a MW to a MR.
138        ///  - `IBV_WC_BAD_RESP_ERR`: Bad Response Error: an unexpected transport layer opcode was
139        ///    returned by the responder. Relevant for RC QPs.
140        ///  - `IBV_WC_LOC_ACCESS_ERR`: Local Access Error: a protection error occurred on a local data
141        ///    buffer during the processing of a RDMA Write with Immediate operation sent from the
142        ///    remote node. Relevant for RC QPs.
143        ///  - `IBV_WC_REM_INV_REQ_ERR`: Remote Invalid Request Error: The responder detected an
144        ///    invalid message on the channel. Possible causes include the operation is not supported
145        ///    by this receive queue (qp_access_flags in remote QP wasn't configured to support this
146        ///    operation), insufficient buffering to receive a new RDMA or Atomic Operation request, or
147        ///    the length specified in a RDMA request is greater than 2^{31} bytes. Relevant for RC
148        ///    QPs.
149        ///  - `IBV_WC_REM_ACCESS_ERR`: Remote Access Error: a protection error occurred on a remote
150        ///    data buffer to be read by an RDMA Read, written by an RDMA Write or accessed by an
151        ///    atomic operation. This error is reported only on RDMA operations or atomic operations.
152        ///    Relevant for RC QPs.
153        ///  - `IBV_WC_REM_OP_ERR`: Remote Operation Error: the operation could not be completed
154        ///    successfully by the responder. Possible causes include a responder QP related error that
155        ///    prevented the responder from completing the request or a malformed WQE on the Receive
156        ///    Queue. Relevant for RC QPs.
157        ///  - `IBV_WC_RETRY_EXC_ERR`: Transport Retry Counter Exceeded: The local transport timeout
158        ///    retry counter was exceeded while trying to send this message. This means that the remote
159        ///    side didn't send any Ack or Nack. If this happens when sending the first message,
160        ///    usually this mean that the connection attributes are wrong or the remote side isn't in a
161        ///    state that it can respond to messages. If this happens after sending the first message,
162        ///    usually it means that the remote QP isn't available anymore. Relevant for RC QPs.
163        ///  - `IBV_WC_RNR_RETRY_EXC_ERR`: RNR Retry Counter Exceeded: The RNR NAK retry count was
164        ///    exceeded. This usually means that the remote side didn't post any WR to its Receive
165        ///    Queue. Relevant for RC QPs.
166        ///  - `IBV_WC_LOC_RDD_VIOL_ERR`: Local RDD Violation Error: The RDD associated with the QP
167        ///    does not match the RDD associated with the EE Context (unused, since its relevant only
168        ///    to RD QPs or EE Context, which aren't supported).
169        ///  - `IBV_WC_REM_INV_RD_REQ_ERR`: Remote Invalid RD Request: The responder detected an
170        ///    invalid incoming RD message. Causes include a Q_Key or RDD violation (unused, since its
171        ///    relevant only to RD QPs or EE Context, which aren't supported)
172        ///  - `IBV_WC_REM_ABORT_ERR`: Remote Aborted Error: For UD or UC QPs associated with a SRQ,
173        ///    the responder aborted the operation.
174        ///  - `IBV_WC_INV_EECN_ERR`: Invalid EE Context Number: An invalid EE Context number was
175        ///    detected (unused, since its relevant only to RD QPs or EE Context, which aren't
176        ///    supported).
177        ///  - `IBV_WC_INV_EEC_STATE_ERR`: Invalid EE Context State Error: Operation is not legal for
178        ///    the specified EE Context state (unused, since its relevant only to RD QPs or EE Context,
179        ///    which aren't supported).
180        ///  - `IBV_WC_FATAL_ERR`: Fatal Error.
181        ///  - `IBV_WC_RESP_TIMEOUT_ERR`: Response Timeout Error.
182        ///  - `IBV_WC_GENERAL_ERR`: General Error: other error which isn't one of the above errors.
183        pub fn error(&self) -> Option<(ibv_wc_status::Type, u32)> {
184            match self.status {
185                ibv_wc_status::IBV_WC_SUCCESS => None,
186                status => Some((status, self.vendor_err)),
187            }
188        }
189
190        /// Returns the operation that the corresponding Work Request performed.
191        ///
192        /// This value controls the way that data was sent, the direction of the data flow and the
193        /// valid attributes in the Work Completion.
194        pub fn opcode(&self) -> ibv_wc_opcode::Type {
195            self.opcode
196        }
197
198        /// Returns a 32 bits number, in network order, in an SEND or RDMA WRITE opcodes that is being
199        /// sent along with the payload to the remote side and placed in a Receive Work Completion and
200        /// not in a remote memory buffer
201        ///
202        /// Note that IMM is only returned if `IBV_WC_WITH_IMM` is set in `wc_flags`. If this is not
203        /// the case, no immediate value was provided, and `imm_data` should be interpreted
204        /// differently. See `man ibv_poll_cq` for details.
205        pub fn imm_data(&self) -> Option<u32> {
206            if self.is_valid() && ((self.wc_flags & ibv_wc_flags::IBV_WC_WITH_IMM).0 != 0) {
207                Some(self.imm_data)
208            } else {
209                None
210            }
211        }
212    }
213
214    impl Default for ibv_wc {
215        fn default() -> Self {
216            ibv_wc {
217                wr_id: 0,
218                status: ibv_wc_status::IBV_WC_GENERAL_ERR,
219                opcode: ibv_wc_opcode::IBV_WC_LOCAL_INV,
220                vendor_err: 0,
221                byte_len: 0,
222                imm_data: 0,
223                qp_num: 0,
224                src_qp: 0,
225                wc_flags: ibv_wc_flags(0),
226                pkey_index: 0,
227                slid: 0,
228                sl: 0,
229                dlid_path_bits: 0,
230            }
231        }
232    }
233}
234
235pub use inner::*;