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}