Skip to main content

ibverbs_rs/ibverbs/work/
request.rs

1use crate::ibverbs::memory::{GatherElement, RemoteMemoryRegion, ScatterElement};
2
3/// A request to send data to a remote peer.
4///
5/// In a Send operation, the local node pushes data to a remote node. The remote node must
6/// have posted a corresponding [`ReceiveWorkRequest`] to accept the data.
7///
8/// # Lifetimes
9///
10/// * `'wr` — The lifetime of this struct. It must live until the request is posted to the Queue Pair.
11/// * `'data` — The lifetime of the local data buffer. It is tied to the [`GatherElement`]
12///   and must remain valid until the operation completes.
13#[derive(Debug, Clone)]
14pub struct SendWorkRequest<'wr, 'data> {
15    pub(crate) gather_elements: &'wr [GatherElement<'data>],
16    pub(crate) imm_data: Option<u32>,
17}
18
19/// A request to receive data from a remote peer.
20///
21/// In a Receive operation, the local node provides a buffer to store incoming data sent by
22/// a remote node. This request must be posted *before* the incoming message arrives.
23///
24/// # Lifetimes
25///
26/// * `'wr` — The lifetime of this struct. It must live until the request is posted to the Queue Pair.
27/// * `'data` — The lifetime of the local data buffer. It is tied to the [`ScatterElement`]
28///   and must remain valid until the operation completes.
29#[derive(Debug)]
30pub struct ReceiveWorkRequest<'wr, 'data> {
31    pub(crate) scatter_elements: &'wr mut [ScatterElement<'data>],
32}
33
34/// A request to write data directly into remote memory.
35///
36/// This operation copies data from local memory (Source) to a specific address in remote
37/// memory (Destination). The remote CPU is not involved.
38///
39/// # Lifetimes
40///
41/// * `'wr` — The lifetime of this struct. It must live until the request is posted to the Queue Pair.
42/// * `'data` — The lifetime of the local data buffer. It is tied to the [`GatherElement`]
43///   and must remain valid until the operation completes.
44#[derive(Debug, Clone)]
45pub struct WriteWorkRequest<'wr, 'data> {
46    pub(crate) gather_elements: &'wr [GatherElement<'data>],
47    pub(crate) remote_mr: RemoteMemoryRegion,
48    pub(crate) imm_data: Option<u32>,
49}
50
51/// A request to read data directly from remote memory.
52///
53/// This operation fetches data from a specific address in remote memory (Source) and
54/// writes it to local memory (Destination).
55///
56/// # Lifetimes
57///
58/// * `'wr` — The lifetime of this struct. It must live until the request is posted to the Queue Pair.
59/// * `'data` — The lifetime of the local data buffer. It is tied to the [`ScatterElement`]
60///   and must remain valid until the operation completes.
61#[derive(Debug)]
62pub struct ReadWorkRequest<'wr, 'data> {
63    pub(crate) scatter_elements: &'wr mut [ScatterElement<'data>],
64    pub(crate) remote_mr: RemoteMemoryRegion,
65}
66
67impl<'wr, 'data> SendWorkRequest<'wr, 'data> {
68    /// Creates a new Send request using the provided list of gather elements.
69    pub fn new(gather_elements: &'wr [GatherElement<'data>]) -> Self {
70        assert!(
71            i32::try_from(gather_elements.len()).is_ok(),
72            "SGE list length {} exceeds i32::MAX",
73            gather_elements.len()
74        );
75        Self {
76            gather_elements,
77            imm_data: None,
78        }
79    }
80
81    /// Attach immediate data (a 32-bit integer) to the operation.
82    pub fn with_immediate(mut self, imm_data: u32) -> Self {
83        self.imm_data = Some(imm_data);
84        self
85    }
86
87    /// Creates a new Send request containing only immediate data (0-byte payload).
88    pub fn only_immediate(imm_data: u32) -> Self {
89        Self {
90            gather_elements: &[],
91            imm_data: Some(imm_data),
92        }
93    }
94}
95
96impl<'wr, 'data> ReceiveWorkRequest<'wr, 'data> {
97    /// Creates a new Receive request using the provided list of scatter elements.
98    pub fn new(scatter_elements: &'wr mut [ScatterElement<'data>]) -> Self {
99        assert!(
100            i32::try_from(scatter_elements.len()).is_ok(),
101            "SGE list length {} exceeds i32::MAX",
102            scatter_elements.len()
103        );
104        Self { scatter_elements }
105    }
106
107    /// Creates a new Receive request with an empty buffer, for receiving only immediate data.
108    pub fn only_immediate() -> Self {
109        Self {
110            scatter_elements: &mut [],
111        }
112    }
113}
114
115impl<'wr, 'data> WriteWorkRequest<'wr, 'data> {
116    /// Creates a new RDMA Write request.
117    ///
118    /// * `gather_elements` — The local source data to write.
119    /// * `remote_slice` — The remote destination memory region.
120    pub fn new(
121        gather_elements: &'wr [GatherElement<'data>],
122        remote_slice: RemoteMemoryRegion,
123    ) -> Self {
124        assert!(
125            i32::try_from(gather_elements.len()).is_ok(),
126            "SGE list length {} exceeds i32::MAX",
127            gather_elements.len()
128        );
129        Self {
130            gather_elements,
131            remote_mr: remote_slice,
132            imm_data: None,
133        }
134    }
135
136    /// Attaches 32 bits of immediate data to the write operation.
137    ///
138    /// The immediate value is delivered to the remote peer via a completion notification.
139    /// **The remote peer must have posted a [`ReceiveWorkRequest`] to capture this.**
140    pub fn with_immediate(mut self, imm_data: u32) -> Self {
141        self.imm_data = Some(imm_data);
142        self
143    }
144}
145
146impl<'wr, 'data> ReadWorkRequest<'wr, 'data> {
147    /// Creates a new RDMA Read request.
148    ///
149    /// * `scatter_elements` — The local destination buffer for the read data.
150    /// * `remote_mr` — The remote source memory region.
151    pub fn new(
152        scatter_elements: &'wr mut [ScatterElement<'data>],
153        remote_mr: RemoteMemoryRegion,
154    ) -> Self {
155        assert!(
156            i32::try_from(scatter_elements.len()).is_ok(),
157            "SGE list length {} exceeds i32::MAX",
158            scatter_elements.len()
159        );
160        Self {
161            scatter_elements,
162            remote_mr,
163        }
164    }
165}