monarch_rdma/backend/ibverbs/
mlx_queue_pair.rs1use std::io::Error;
12use std::result::Result;
13use std::sync::Arc;
14
15use super::domain::IbvDomain;
16use super::domain::IbvDomainImpl;
17use super::memory_region::IbvMemoryRegionView;
18use super::memory_region::IbvRemoteMemoryRegionView;
19use super::primitives::GidScope;
20use super::primitives::GidType;
21use super::primitives::IbvConfig;
22use super::primitives::IbvCq;
23use super::primitives::IbvQp;
24use super::primitives::IbvQpInfo;
25use super::queue_pair::IbvQueuePair;
26use super::queue_pair::RCQueuePair;
27
28#[derive(Debug)]
35pub struct MlxQueuePair(RCQueuePair);
36
37impl MlxQueuePair {
38 pub(super) unsafe fn create_ibv_qp<I: IbvDomainImpl>(
51 domain: &IbvDomain<I>,
52 config: &IbvConfig,
53 send_cq: Arc<IbvCq>,
54 recv_cq: Arc<IbvCq>,
55 ) -> Result<IbvQp, anyhow::Error> {
56 let context = domain.context().as_ptr();
57 let pd = domain.as_ptr();
58 if pd.is_null() {
59 anyhow::bail!("cannot create an MlxQueuePair on a null protection domain");
60 }
61
62 let mut init_attr = rdmaxcel_sys::ibv_qp_init_attr_ex {
66 send_cq: send_cq.as_ptr(),
67 recv_cq: recv_cq.as_ptr(),
68 cap: rdmaxcel_sys::ibv_qp_cap {
69 max_send_wr: config.max_send_wr,
70 max_recv_wr: config.max_recv_wr,
71 max_send_sge: config.max_send_sge,
72 max_recv_sge: config.max_recv_sge,
73 max_inline_data: 0,
74 },
75 qp_type: rdmaxcel_sys::ibv_qp_type::IBV_QPT_RC,
76 sq_sig_all: 0,
77 pd,
78 comp_mask: rdmaxcel_sys::IBV_QP_INIT_ATTR_PD
79 | rdmaxcel_sys::IBV_QP_INIT_ATTR_SEND_OPS_FLAGS,
80 send_ops_flags: (rdmaxcel_sys::IBV_QP_EX_WITH_RDMA_WRITE
81 | rdmaxcel_sys::IBV_QP_EX_WITH_RDMA_READ
82 | rdmaxcel_sys::IBV_QP_EX_WITH_SEND) as u64,
83 ..Default::default()
84 };
85 let mut mlx5dv_attr = rdmaxcel_sys::mlx5dv_qp_init_attr {
86 comp_mask: rdmaxcel_sys::MLX5DV_QP_INIT_ATTR_MASK_SEND_OPS_FLAGS as u64,
87 send_ops_flags: (rdmaxcel_sys::MLX5DV_QP_EX_WITH_MKEY_CONFIGURE
88 | rdmaxcel_sys::MLX5DV_QP_EX_WITH_MR_LIST) as u64,
89 ..Default::default()
90 };
91 let qp =
97 unsafe { rdmaxcel_sys::mlx5dv_create_qp(context, &mut init_attr, &mut mlx5dv_attr) };
98 if qp.is_null() {
99 anyhow::bail!(
100 "failed to create mlx5dv queue pair (QP): {}",
101 Error::last_os_error()
102 );
103 }
104 Ok(unsafe { IbvQp::from_raw(qp, send_cq, recv_cq, domain.pd().clone()) })
108 }
109}
110
111impl IbvQueuePair for MlxQueuePair {
112 unsafe fn new<I: IbvDomainImpl<QueuePair = Self>>(
113 domain: &IbvDomain<I>,
114 config: IbvConfig,
115 send_cq: Arc<IbvCq>,
116 recv_cq: Arc<IbvCq>,
117 ) -> Result<Self, anyhow::Error> {
118 tracing::debug!("creating an MlxQueuePair from config {}", config);
119 let gid = domain.device_info().select_gid(
120 config.port_num,
121 Some(GidScope::Global),
122 Some(GidType::RoCEv2),
123 )?;
124 let qp = unsafe { Self::create_ibv_qp(domain, &config, send_cq, recv_cq) }?;
127 let access_flags = domain.access_flags();
128 Ok(MlxQueuePair(unsafe {
131 RCQueuePair::from_qp(qp, config, gid, access_flags)
132 }))
133 }
134
135 fn connect(&mut self, info: &IbvQpInfo) -> Result<(), anyhow::Error> {
136 self.0.connect(info)
137 }
138
139 fn get_qp_info(&mut self) -> Result<IbvQpInfo, anyhow::Error> {
140 self.0.get_qp_info()
141 }
142
143 fn state(&mut self) -> Result<u32, anyhow::Error> {
144 self.0.state()
145 }
146
147 fn put(
148 &mut self,
149 remote_dst: IbvRemoteMemoryRegionView,
150 local_src: IbvMemoryRegionView,
151 ) -> Result<Vec<u64>, anyhow::Error> {
152 self.0.put(remote_dst, local_src)
153 }
154
155 fn get(
156 &mut self,
157 local_dst: IbvMemoryRegionView,
158 remote_src: IbvRemoteMemoryRegionView,
159 ) -> Result<Vec<u64>, anyhow::Error> {
160 self.0.get(local_dst, remote_src)
161 }
162}