ibverbs_rs/ibverbs/queue_pair/
ops.rs1use crate::ibverbs::error::{IbvError, IbvResult};
15use crate::ibverbs::queue_pair::QueuePair;
16use crate::ibverbs::work::{
17 ReadWorkRequest, ReceiveWorkRequest, SendWorkRequest, WriteWorkRequest,
18};
19use ibverbs_sys::*;
20use std::ptr;
21
22impl QueuePair {
23 pub unsafe fn post_send(&mut self, wr: SendWorkRequest, wr_id: u64) -> IbvResult<()> {
33 let (opcode, __bindgen_anon_1) = match wr.imm_data {
34 None => (ibv_wr_opcode::IBV_WR_SEND, Default::default()),
35 Some(imm_data) => (
36 ibv_wr_opcode::IBV_WR_SEND_WITH_IMM,
37 ibv_send_wr__bindgen_ty_1 {
38 imm_data: imm_data.to_be(),
39 },
40 ),
41 };
42
43 #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
44 let mut wr = ibv_send_wr {
46 wr_id,
47 next: ptr::null::<ibv_send_wr>() as *mut _,
48 sg_list: wr.gather_elements.as_ref().as_ptr() as *mut ibv_sge,
49 num_sge: wr.gather_elements.as_ref().len() as i32,
50 opcode,
51 send_flags: ibv_send_flags::IBV_SEND_SIGNALED.0,
52 wr: Default::default(),
53 qp_type: Default::default(),
54 __bindgen_anon_1,
55 __bindgen_anon_2: Default::default(),
56 };
57
58 unsafe {
59 self.post_send_wr(&mut wr).map_err(|errno| {
60 IbvError::from_errno_with_msg(errno, "Failed to post send work request")
61 })
62 }
63 }
64
65 pub unsafe fn post_receive(&mut self, wr: ReceiveWorkRequest, wr_id: u64) -> IbvResult<()> {
74 #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
75 let mut wr = ibv_recv_wr {
77 wr_id,
78 next: ptr::null::<ibv_send_wr>() as *mut _,
79 sg_list: wr.scatter_elements.as_mut().as_mut_ptr() as *mut ibv_sge,
80 num_sge: wr.scatter_elements.as_mut().len() as i32,
81 };
82
83 unsafe {
84 self.post_receive_wr(&mut wr).map_err(|errno| {
85 IbvError::from_errno_with_msg(errno, "Failed to post receive work request")
86 })
87 }
88 }
89
90 pub unsafe fn post_write(&mut self, wr: WriteWorkRequest, wr_id: u64) -> IbvResult<()> {
100 let (opcode, __bindgen_anon_1) = match wr.imm_data {
101 None => (ibv_wr_opcode::IBV_WR_RDMA_WRITE, Default::default()),
102 Some(imm_data) => (
103 ibv_wr_opcode::IBV_WR_RDMA_WRITE_WITH_IMM,
104 ibv_send_wr__bindgen_ty_1 {
105 imm_data: imm_data.to_be(),
106 },
107 ),
108 };
109
110 #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
111 let mut wr = ibv_send_wr {
113 wr_id,
114 next: ptr::null::<ibv_send_wr>() as *mut _,
115 sg_list: wr.gather_elements.as_ptr() as *mut ibv_sge,
116 num_sge: wr.gather_elements.len() as i32,
117 opcode,
118 send_flags: ibv_send_flags::IBV_SEND_SIGNALED.0,
119 wr: ibv_send_wr__bindgen_ty_2 {
120 rdma: ibv_send_wr__bindgen_ty_2__bindgen_ty_1 {
121 remote_addr: wr.remote_mr.address(),
122 rkey: wr.remote_mr.rkey(),
123 },
124 },
125 qp_type: Default::default(),
126 __bindgen_anon_1,
127 __bindgen_anon_2: Default::default(),
128 };
129
130 unsafe {
131 self.post_send_wr(&mut wr).map_err(|errno| {
132 IbvError::from_errno_with_msg(errno, "Failed to post write work request")
133 })
134 }
135 }
136
137 pub unsafe fn post_read(&mut self, wr: ReadWorkRequest, wr_id: u64) -> IbvResult<()> {
144 #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
146 let mut wr = ibv_send_wr {
147 wr_id,
148 next: ptr::null::<ibv_send_wr>() as *mut _,
149 sg_list: wr.scatter_elements.as_ptr() as *mut ibv_sge,
150 num_sge: wr.scatter_elements.len() as i32,
151 opcode: ibv_wr_opcode::IBV_WR_RDMA_READ,
152 send_flags: ibv_send_flags::IBV_SEND_SIGNALED.0,
153 wr: ibv_send_wr__bindgen_ty_2 {
154 rdma: ibv_send_wr__bindgen_ty_2__bindgen_ty_1 {
155 remote_addr: wr.remote_mr.address(),
156 rkey: wr.remote_mr.rkey(),
157 },
158 },
159 qp_type: Default::default(),
160 __bindgen_anon_1: Default::default(),
161 __bindgen_anon_2: Default::default(),
162 };
163
164 unsafe { self.post_send_wr(&mut wr) }.map_err(|errno| {
165 IbvError::from_errno_with_msg(errno, "Failed to post read work request")
166 })
167 }
168
169 #[inline(always)]
170 unsafe fn post_send_wr(&mut self, wr: &mut ibv_send_wr) -> Result<(), i32> {
171 let mut bad_wr: *mut ibv_send_wr = ptr::null::<ibv_send_wr>() as *mut _;
172 let ctx = unsafe { (*self.qp).context };
173 let post_send = unsafe {
174 (*ctx)
175 .ops
176 .post_send
177 .expect("post_send function pointer should be set by driver")
178 };
179 let errno = unsafe { post_send(self.qp, wr as *mut _, &mut bad_wr as *mut _) };
180 if errno != 0 { Err(errno) } else { Ok(()) }
181 }
182
183 #[inline(always)]
184 unsafe fn post_receive_wr(&mut self, wr: &mut ibv_recv_wr) -> Result<(), i32> {
185 let mut bad_wr: *mut ibv_recv_wr = ptr::null::<ibv_recv_wr>() as *mut _;
186 let ctx = unsafe { (*self.qp).context };
187 let post_recv = unsafe {
188 (*ctx)
189 .ops
190 .post_recv
191 .expect("post_recv function pointer should be set by driver")
192 };
193 let errno = unsafe { post_recv(self.qp, wr as *mut _, &mut bad_wr as *mut _) };
194 if errno != 0 { Err(errno) } else { Ok(()) }
195 }
196}