Skip to content

Commit d89f870

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 d89f870

File tree

9 files changed

+376
-153
lines changed

9 files changed

+376
-153
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

+111-85
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::{
3535
};
3636

3737
use crate::core::MayastorEnvironment;
38+
use strum_macros::{AsRefStr, EnumString, EnumVariantNames};
3839

3940
pub trait GetOpts {
4041
fn get(&self) -> Self;
@@ -84,6 +85,88 @@ impl GetOpts for NexusOpts {
8485
/// Must be equal to the size of `spdk_nvmf_target_opts.crdt`.
8586
pub const TARGET_CRDT_LEN: usize = 3;
8687

88+
#[derive(Clone, Default, EnumString, EnumVariantNames, AsRefStr)]
89+
#[strum(serialize_all = "lowercase")]
90+
pub enum NvmfTgtTransport {
91+
Rdma,
92+
#[default]
93+
Tcp,
94+
}
95+
96+
/// Nvmf settings for the transports
97+
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
98+
#[serde(default, deny_unknown_fields)]
99+
pub struct NvmfTransportOpts {
100+
/// max queue depth
101+
max_queue_depth: u16,
102+
/// max qpairs per controller
103+
max_qpairs_per_ctrl: u16,
104+
/// encapsulated data size
105+
in_capsule_data_size: u32,
106+
/// max IO size
107+
max_io_size: u32,
108+
/// IO unit size
109+
io_unit_size: u32,
110+
/// max admin queue depth per admin queue
111+
max_aq_depth: u32,
112+
/// num of shared buffers
113+
num_shared_buf: u32,
114+
/// cache size
115+
buf_cache_size: u32,
116+
/// dif
117+
dif_insert_or_strip: bool,
118+
/// abort execution timeout
119+
abort_timeout_sec: u32,
120+
/// acceptor poll rate, microseconds
121+
acceptor_poll_rate: u32,
122+
/// Use zero-copy operations if the underlying bdev supports them
123+
zcopy: bool,
124+
/// ACK timeout in milliseconds
125+
ack_timeout: u32,
126+
/// Size of RDMA data WR pool
127+
data_wr_pool_size: u32,
128+
}
129+
130+
impl NvmfTransportOpts {
131+
/// Tweak a few opts more suited for rdma.
132+
fn for_rdma(mut self) -> Self {
133+
self.in_capsule_data_size = try_from_env(
134+
"NVMF_RDMA_IN_CAPSULE_DATA_SIZE",
135+
self.in_capsule_data_size,
136+
);
137+
self.io_unit_size = try_from_env("NVMF_RDMA_IO_UNIT_SIZE", 8192); // SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE
138+
self.data_wr_pool_size =
139+
try_from_env("NVMF_RDMA_DATA_WR_POOL_SIZE", 4095); // SPDK_NVMF_RDMA_DEFAULT_DATA_WR_POOL_SIZE
140+
self.num_shared_buf =
141+
try_from_env("NVMF_RDMA_NUM_SHARED_BUF", self.num_shared_buf);
142+
self
143+
}
144+
}
145+
146+
impl Default for NvmfTransportOpts {
147+
fn default() -> Self {
148+
Self {
149+
max_queue_depth: try_from_env("NVMF_TCP_MAX_QUEUE_DEPTH", 32),
150+
in_capsule_data_size: 4096,
151+
max_io_size: 131_072,
152+
io_unit_size: 131_072,
153+
max_qpairs_per_ctrl: try_from_env(
154+
"NVMF_TCP_MAX_QPAIRS_PER_CTRL",
155+
32,
156+
),
157+
num_shared_buf: try_from_env("NVMF_TCP_NUM_SHARED_BUF", 2047),
158+
buf_cache_size: try_from_env("NVMF_TCP_BUF_CACHE_SIZE", 64),
159+
dif_insert_or_strip: false,
160+
max_aq_depth: 32,
161+
abort_timeout_sec: 1,
162+
acceptor_poll_rate: try_from_env("NVMF_ACCEPTOR_POLL_RATE", 10_000),
163+
zcopy: try_from_env("NVMF_ZCOPY", 1) == 1,
164+
ack_timeout: try_from_env("NVMF_ACK_TIMEOUT", 0),
165+
data_wr_pool_size: 0,
166+
}
167+
}
168+
}
169+
87170
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88171
#[serde(default, deny_unknown_fields)]
89172
pub struct NvmfTgtConfig {
@@ -94,11 +177,13 @@ pub struct NvmfTgtConfig {
94177
/// NVMF target Command Retry Delay in x100 ms.
95178
pub crdt: [u16; TARGET_CRDT_LEN],
96179
/// TCP transport options
97-
pub opts: NvmfTcpTransportOpts,
180+
pub opts_tcp: NvmfTransportOpts,
98181
/// NVMF target interface (ip, mac, name or subnet).
99182
pub interface: Option<String>,
100183
/// Enable RDMA for NVMF target or not
101184
pub rdma: Option<bool>,
185+
/// RDMA transport options
186+
pub opts_rdma: NvmfTransportOpts,
102187
}
103188

104189
impl From<NvmfTgtConfig> for Box<spdk_nvmf_target_opts> {
@@ -126,9 +211,10 @@ impl Default for NvmfTgtConfig {
126211
name: "mayastor_target".to_string(),
127212
max_namespaces: 2048,
128213
crdt: args.nvmf_tgt_crdt,
129-
opts: NvmfTcpTransportOpts::default(),
214+
opts_tcp: NvmfTransportOpts::default(),
130215
interface: None,
131216
rdma: None,
217+
opts_rdma: NvmfTransportOpts::default().for_rdma(),
132218
}
133219
}
134220
}
@@ -139,40 +225,6 @@ impl GetOpts for NvmfTgtConfig {
139225
}
140226
}
141227

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-
176228
/// try to read an env variable or returns the default when not found
177229
pub(crate) fn try_from_env<T>(name: &str, default: T) -> T
178230
where
@@ -264,58 +316,32 @@ where
264316
}
265317
}
266318

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-
291319
/// we cannot add derives for YAML to these structs directly, so we need to
292320
/// copy them. The upside though, is that if the FFI structures change, we will
293321
/// 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-
)
322+
impl From<NvmfTransportOpts> for spdk_nvmf_transport_opts {
323+
fn from(o: NvmfTransportOpts) -> Self {
324+
Self {
325+
max_queue_depth: o.max_queue_depth,
326+
max_qpairs_per_ctrlr: o.max_qpairs_per_ctrl,
327+
in_capsule_data_size: o.in_capsule_data_size,
328+
max_io_size: o.max_io_size,
329+
io_unit_size: o.io_unit_size,
330+
max_aq_depth: o.max_aq_depth,
331+
num_shared_buffers: o.num_shared_buf,
332+
buf_cache_size: o.buf_cache_size,
333+
dif_insert_or_strip: o.dif_insert_or_strip,
334+
reserved29: Default::default(),
335+
abort_timeout_sec: o.abort_timeout_sec,
336+
association_timeout: 120000,
337+
transport_specific: std::ptr::null(),
338+
opts_size: std::mem::size_of::<spdk_nvmf_transport_opts>() as u64,
339+
acceptor_poll_rate: o.acceptor_poll_rate,
340+
zcopy: o.zcopy,
341+
ack_timeout: o.ack_timeout,
342+
data_wr_pool_size: o.data_wr_pool_size,
343+
reserved61: Default::default(),
344+
}
319345
}
320346
}
321347

0 commit comments

Comments
 (0)