Skip to content

Commit 11ab2ee

Browse files
wllenyjjiangliu
authored andcommitted
async_runtime: add probe of io_uring support
Signed-off-by: wanglei01 <[email protected]>
1 parent 40b8ba1 commit 11ab2ee

File tree

3 files changed

+67
-13
lines changed

3 files changed

+67
-13
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ build = "build.rs"
2020
arc-swap = "1.5"
2121
async-trait = { version = "0.1.42", optional = true }
2222
bitflags = "1.1"
23+
io-uring = { version = "0.5.8", optional = true }
2324
libc = "0.2.68"
2425
log = "0.4.6"
2526
mio = { version = "0.8", features = ["os-poll", "os-ext"]}
@@ -46,7 +47,7 @@ vm-memory = { version = "0.9", features = ["backend-mmap", "backend-bitmap"] }
4647

4748
[features]
4849
default = ["fusedev"]
49-
async-io = ["async-trait", "tokio-uring", "tokio/fs", "tokio/net", "tokio/sync", "tokio/rt", "tokio/macros"]
50+
async-io = ["async-trait", "tokio-uring", "tokio/fs", "tokio/net", "tokio/sync", "tokio/rt", "tokio/macros", "io-uring"]
5051
fusedev = ["vmm-sys-util", "caps", "core-foundation-sys"]
5152
virtiofs = ["virtio-queue", "caps"]
5253
vhost-user-fs = ["virtiofs", "vhost", "caps"]

src/common/async_file.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::io::{ErrorKind, IoSlice, IoSliceMut};
99
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
1010
use std::path::Path;
1111

12-
use crate::async_runtime::{Runtime, CURRENT_RUNTIME};
12+
use crate::async_runtime::{RuntimeType, RUNTIME_TYPE};
1313
use crate::file_buf::FileVolatileBuf;
1414
use crate::{off64_t, preadv64, pwritev64};
1515

@@ -29,22 +29,16 @@ impl File {
2929
write: bool,
3030
create: bool,
3131
) -> std::io::Result<Self> {
32-
let ty = CURRENT_RUNTIME.with(|rt| match rt {
33-
Runtime::Tokio(_) => 1,
34-
#[cfg(target_os = "linux")]
35-
Runtime::Uring(_) => 2,
36-
});
37-
38-
match ty {
39-
1 => tokio::fs::OpenOptions::new()
32+
match *RUNTIME_TYPE {
33+
RuntimeType::Tokio => tokio::fs::OpenOptions::new()
4034
.read(true)
4135
.write(write)
4236
.create(create)
4337
.open(path)
4438
.await
4539
.map(File::Tokio),
4640
#[cfg(target_os = "linux")]
47-
2 => tokio_uring::fs::OpenOptions::new()
41+
RuntimeType::Uring => tokio_uring::fs::OpenOptions::new()
4842
.read(true)
4943
.write(write)
5044
.create(create)

src/common/async_runtime.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,66 @@
66
77
use std::future::Future;
88

9+
use lazy_static::lazy_static;
10+
11+
lazy_static! {
12+
pub(crate) static ref RUNTIME_TYPE: RuntimeType = RuntimeType::new();
13+
}
14+
15+
pub(crate) enum RuntimeType {
16+
Tokio,
17+
#[cfg(target_os = "linux")]
18+
Uring,
19+
}
20+
21+
impl RuntimeType {
22+
fn new() -> Self {
23+
#[cfg(target_os = "linux")]
24+
{
25+
if Self::probe_io_uring() {
26+
return Self::Uring;
27+
}
28+
}
29+
Self::Tokio
30+
}
31+
32+
#[cfg(target_os = "linux")]
33+
fn probe_io_uring() -> bool {
34+
use io_uring::{opcode, IoUring, Probe};
35+
36+
let io_uring = match IoUring::new(1) {
37+
Ok(io_uring) => io_uring,
38+
Err(_) => {
39+
return false;
40+
}
41+
};
42+
let submitter = io_uring.submitter();
43+
44+
let mut probe = Probe::new();
45+
46+
// Check we can register a probe to validate supported operations.
47+
if let Err(_) = submitter.register_probe(&mut probe) {
48+
return false;
49+
}
50+
51+
// Check IORING_OP_FSYNC is supported
52+
if !probe.is_supported(opcode::Fsync::CODE) {
53+
return false;
54+
}
55+
56+
// Check IORING_OP_READ is supported
57+
if !probe.is_supported(opcode::Read::CODE) {
58+
return false;
59+
}
60+
61+
// Check IORING_OP_WRITE is supported
62+
if !probe.is_supported(opcode::Write::CODE) {
63+
return false;
64+
}
65+
return true;
66+
}
67+
}
68+
969
/// An adapter enum to support both tokio current-thread Runtime and tokio-uring Runtime.
1070
pub enum Runtime {
1171
/// Tokio current thread Runtime.
@@ -26,8 +86,7 @@ impl Runtime {
2686
pub fn new() -> Self {
2787
// Check whether io-uring is available.
2888
#[cfg(target_os = "linux")]
29-
{
30-
// TODO: use io-uring probe to detect supported operations.
89+
if matches!(*RUNTIME_TYPE, RuntimeType::Uring) {
3190
if let Ok(rt) = tokio_uring::Runtime::new(&tokio_uring::builder()) {
3291
return Runtime::Uring(std::sync::Mutex::new(rt));
3392
}

0 commit comments

Comments
 (0)