Skip to content

Commit be97071

Browse files
committed
feat: add RDMA listener to Mayastor Nvmf target
This adds the capability to listen for rdma connections to the Mayastor Nvmf target if the rdma feature is enabled during installation. Any Nvmf subsystem facing the host i.e. the nexus nvmf subsystem will now be able to support tcp and rdma both. Signed-off-by: Diwakar Sharma <diwakar.sharma@datacore.com>
1 parent c661e1b commit be97071

File tree

9 files changed

+378
-154
lines changed

9 files changed

+378
-154
lines changed

io-engine/src/bin/io-engine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ fn start_tokio_runtime(args: &MayastorCliArgs) {
108108

109109
if args.rdma {
110110
env::set_var("ENABLE_RDMA", "true");
111-
warn!("RDMA is enabled for Mayastor NVMEoF target");
111+
warn!("RDMA is requested to be enabled for Mayastor NVMEoF target");
112112
}
113113

114114
unsafe {

io-engine/src/core/bdev.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use snafu::ResultExt;
1111
use spdk_rs::libspdk::{spdk_bdev, spdk_get_ticks_hz};
1212

1313
use crate::{
14-
bdev::bdev_event_callback,
14+
bdev::{bdev_event_callback, nexus::NEXUS_MODULE_NAME},
1515
bdev_api::bdev_uri_eq,
1616
core::{
1717
share::{NvmfShareProps, Protocol, Share, UpdateProps},
@@ -210,6 +210,7 @@ where
210210
) -> Result<Self::Output, Self::Error> {
211211
let me = unsafe { self.get_unchecked_mut() };
212212
let props = NvmfShareProps::from(props);
213+
let is_nexus_bdev = me.driver() == NEXUS_MODULE_NAME;
213214

214215
let ptpl = props.ptpl().as_ref().map(|ptpl| ptpl.path());
215216

@@ -232,7 +233,7 @@ where
232233
.await
233234
.context(ShareNvmf {})?;
234235

235-
subsystem.start().await.context(ShareNvmf {})
236+
subsystem.start(is_nexus_bdev).await.context(ShareNvmf {})
236237
}
237238

238239
fn create_ptpl(&self) -> Result<Option<PtplProps>, Self::Error> {

io-engine/src/core/env.rs

+5
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,11 @@ impl MayastorEnvironment {
834834
.map(|s| s.clone())
835835
}
836836

837+
/// Check if RDMA needs to be enabled for Mayastor nvmf target.
838+
pub fn rdma(&self) -> bool {
839+
self.rdma
840+
}
841+
837842
/// Detects IP address for NVMF target by the interface specified in CLI
838843
/// arguments.
839844
fn detect_nvmf_tgt_iface_ip(iface: &str) -> Result<String, String> {

io-engine/src/subsys/config/opts.rs

+116-86
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use spdk_rs::{
2828

2929
use std::{
3030
convert::TryFrom,
31-
fmt::{Debug, Display},
31+
fmt::{Debug, Display, Formatter},
3232
mem::zeroed,
3333
ptr::null_mut,
3434
str::FromStr,
@@ -84,6 +84,93 @@ impl GetOpts for NexusOpts {
8484
/// Must be equal to the size of `spdk_nvmf_target_opts.crdt`.
8585
pub const TARGET_CRDT_LEN: usize = 3;
8686

87+
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
88+
pub enum NvmfTgtTransport {
89+
Rdma,
90+
#[default]
91+
Tcp,
92+
}
93+
94+
impl Display for NvmfTgtTransport {
95+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96+
write!(
97+
f,
98+
"{}",
99+
match self {
100+
NvmfTgtTransport::Rdma => "rdma",
101+
NvmfTgtTransport::Tcp => "tcp",
102+
}
103+
)
104+
}
105+
}
106+
107+
/// Nvmf settings for the transports
108+
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
109+
#[serde(default, deny_unknown_fields)]
110+
pub struct NvmfTransportOpts {
111+
/// max queue depth
112+
max_queue_depth: u16,
113+
/// max qpairs per controller
114+
max_qpairs_per_ctrl: u16,
115+
/// encapsulated data size
116+
in_capsule_data_size: u32,
117+
/// max IO size
118+
max_io_size: u32,
119+
/// IO unit size
120+
io_unit_size: u32,
121+
/// max admin queue depth per admin queue
122+
max_aq_depth: u32,
123+
/// num of shared buffers
124+
num_shared_buf: u32,
125+
/// cache size
126+
buf_cache_size: u32,
127+
/// dif
128+
dif_insert_or_strip: bool,
129+
/// abort execution timeout
130+
abort_timeout_sec: u32,
131+
/// acceptor poll rate, microseconds
132+
acceptor_poll_rate: u32,
133+
/// Use zero-copy operations if the underlying bdev supports them
134+
zcopy: bool,
135+
/// ACK timeout in milliseconds
136+
ack_timeout: u32,
137+
/// Size of RDMA data WR pool
138+
data_wr_pool_size: u32,
139+
}
140+
141+
impl NvmfTransportOpts {
142+
fn for_rdma(mut self) -> Self {
143+
self.in_capsule_data_size = 4096;
144+
self.io_unit_size = 8192; // SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE
145+
self.data_wr_pool_size = 4095; // SPDK_NVMF_RDMA_DEFAULT_DATA_WR_POOL_SIZE
146+
self
147+
}
148+
}
149+
150+
impl Default for NvmfTransportOpts {
151+
fn default() -> Self {
152+
Self {
153+
max_queue_depth: try_from_env("NVMF_TCP_MAX_QUEUE_DEPTH", 32),
154+
in_capsule_data_size: 4096,
155+
max_io_size: 131_072,
156+
io_unit_size: 131_072,
157+
max_qpairs_per_ctrl: try_from_env(
158+
"NVMF_TCP_MAX_QPAIRS_PER_CTRL",
159+
32,
160+
),
161+
num_shared_buf: try_from_env("NVMF_TCP_NUM_SHARED_BUF", 2047),
162+
buf_cache_size: try_from_env("NVMF_TCP_BUF_CACHE_SIZE", 64),
163+
dif_insert_or_strip: false,
164+
max_aq_depth: 32,
165+
abort_timeout_sec: 1,
166+
acceptor_poll_rate: try_from_env("NVMF_ACCEPTOR_POLL_RATE", 10_000),
167+
zcopy: try_from_env("NVMF_ZCOPY", 1) == 1,
168+
ack_timeout: try_from_env("NVMF_ACK_TIMEOUT", 0),
169+
data_wr_pool_size: try_from_env("NVMF_DATA_WR_POOL_SIZE", 0),
170+
}
171+
}
172+
}
173+
87174
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88175
#[serde(default, deny_unknown_fields)]
89176
pub struct NvmfTgtConfig {
@@ -94,11 +181,13 @@ pub struct NvmfTgtConfig {
94181
/// NVMF target Command Retry Delay in x100 ms.
95182
pub crdt: [u16; TARGET_CRDT_LEN],
96183
/// TCP transport options
97-
pub opts: NvmfTcpTransportOpts,
184+
pub opts_tcp: NvmfTransportOpts,
98185
/// NVMF target interface (ip, mac, name or subnet).
99186
pub interface: Option<String>,
100187
/// Enable RDMA for NVMF target or not
101188
pub rdma: Option<bool>,
189+
/// RDMA transport options
190+
pub opts_rdma: NvmfTransportOpts,
102191
}
103192

104193
impl From<NvmfTgtConfig> for Box<spdk_nvmf_target_opts> {
@@ -126,9 +215,10 @@ impl Default for NvmfTgtConfig {
126215
name: "mayastor_target".to_string(),
127216
max_namespaces: 2048,
128217
crdt: args.nvmf_tgt_crdt,
129-
opts: NvmfTcpTransportOpts::default(),
218+
opts_tcp: NvmfTransportOpts::default(),
130219
interface: None,
131220
rdma: None,
221+
opts_rdma: NvmfTransportOpts::default().for_rdma(),
132222
}
133223
}
134224
}
@@ -139,40 +229,6 @@ impl GetOpts for NvmfTgtConfig {
139229
}
140230
}
141231

142-
/// Settings for the TCP transport
143-
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
144-
#[serde(default, deny_unknown_fields)]
145-
pub struct NvmfTcpTransportOpts {
146-
/// max queue depth
147-
max_queue_depth: u16,
148-
/// max qpairs per controller
149-
max_qpairs_per_ctrl: u16,
150-
/// encapsulated data size
151-
in_capsule_data_size: u32,
152-
/// max IO size
153-
max_io_size: u32,
154-
/// IO unit size
155-
io_unit_size: u32,
156-
/// max admin queue depth per admin queue
157-
max_aq_depth: u32,
158-
/// num of shared buffers
159-
num_shared_buf: u32,
160-
/// cache size
161-
buf_cache_size: u32,
162-
/// dif
163-
dif_insert_or_strip: bool,
164-
/// abort execution timeout
165-
abort_timeout_sec: u32,
166-
/// acceptor poll rate, microseconds
167-
acceptor_poll_rate: u32,
168-
/// Use zero-copy operations if the underlying bdev supports them
169-
zcopy: bool,
170-
/// ACK timeout in milliseconds
171-
ack_timeout: u32,
172-
/// Size of RDMA data WR pool
173-
data_wr_pool_size: u32,
174-
}
175-
176232
/// try to read an env variable or returns the default when not found
177233
pub(crate) fn try_from_env<T>(name: &str, default: T) -> T
178234
where
@@ -264,58 +320,32 @@ where
264320
}
265321
}
266322

267-
impl Default for NvmfTcpTransportOpts {
268-
fn default() -> Self {
269-
Self {
270-
max_queue_depth: try_from_env("NVMF_TCP_MAX_QUEUE_DEPTH", 32),
271-
in_capsule_data_size: 4096,
272-
max_io_size: 131_072,
273-
io_unit_size: 131_072,
274-
max_qpairs_per_ctrl: try_from_env(
275-
"NVMF_TCP_MAX_QPAIRS_PER_CTRL",
276-
32,
277-
),
278-
num_shared_buf: try_from_env("NVMF_TCP_NUM_SHARED_BUF", 2047),
279-
buf_cache_size: try_from_env("NVMF_TCP_BUF_CACHE_SIZE", 64),
280-
dif_insert_or_strip: false,
281-
max_aq_depth: 32,
282-
abort_timeout_sec: 1,
283-
acceptor_poll_rate: try_from_env("NVMF_ACCEPTOR_POLL_RATE", 10_000),
284-
zcopy: try_from_env("NVMF_ZCOPY", 1) == 1,
285-
ack_timeout: try_from_env("NVMF_ACK_TIMEOUT", 0),
286-
data_wr_pool_size: try_from_env("NVMF_DATA_WR_POOL_SIZE", 0),
287-
}
288-
}
289-
}
290-
291323
/// we cannot add derives for YAML to these structs directly, so we need to
292324
/// copy them. The upside though, is that if the FFI structures change, we will
293325
/// know about it during compile time.
294-
impl From<NvmfTcpTransportOpts> for spdk_nvmf_transport_opts {
295-
fn from(o: NvmfTcpTransportOpts) -> Self {
296-
struct_size_init!(
297-
Self {
298-
max_queue_depth: o.max_queue_depth,
299-
max_qpairs_per_ctrlr: o.max_qpairs_per_ctrl,
300-
in_capsule_data_size: o.in_capsule_data_size,
301-
max_io_size: o.max_io_size,
302-
io_unit_size: o.io_unit_size,
303-
max_aq_depth: o.max_aq_depth,
304-
num_shared_buffers: o.num_shared_buf,
305-
buf_cache_size: o.buf_cache_size,
306-
dif_insert_or_strip: o.dif_insert_or_strip,
307-
reserved29: Default::default(),
308-
abort_timeout_sec: o.abort_timeout_sec,
309-
association_timeout: 120000,
310-
transport_specific: std::ptr::null(),
311-
acceptor_poll_rate: o.acceptor_poll_rate,
312-
zcopy: o.zcopy,
313-
reserved61: Default::default(),
314-
ack_timeout: o.ack_timeout,
315-
data_wr_pool_size: o.data_wr_pool_size,
316-
},
317-
opts_size
318-
)
326+
impl From<NvmfTransportOpts> for spdk_nvmf_transport_opts {
327+
fn from(o: NvmfTransportOpts) -> Self {
328+
Self {
329+
max_queue_depth: o.max_queue_depth,
330+
max_qpairs_per_ctrlr: o.max_qpairs_per_ctrl,
331+
in_capsule_data_size: o.in_capsule_data_size,
332+
max_io_size: o.max_io_size,
333+
io_unit_size: o.io_unit_size,
334+
max_aq_depth: o.max_aq_depth,
335+
num_shared_buffers: o.num_shared_buf,
336+
buf_cache_size: o.buf_cache_size,
337+
dif_insert_or_strip: o.dif_insert_or_strip,
338+
reserved29: Default::default(),
339+
abort_timeout_sec: o.abort_timeout_sec,
340+
association_timeout: 120000,
341+
transport_specific: std::ptr::null(),
342+
opts_size: std::mem::size_of::<spdk_nvmf_transport_opts>() as u64,
343+
acceptor_poll_rate: o.acceptor_poll_rate,
344+
zcopy: o.zcopy,
345+
ack_timeout: o.ack_timeout,
346+
data_wr_pool_size: o.data_wr_pool_size,
347+
reserved61: Default::default(),
348+
}
319349
}
320350
}
321351

0 commit comments

Comments
 (0)