diff --git a/src/io_uring.rs b/src/io_uring.rs index 4783d7d6..7ed3d63e 100644 --- a/src/io_uring.rs +++ b/src/io_uring.rs @@ -17,8 +17,9 @@ use { pending_result::PendingResults, sys::{ IORING_ENTER_GETEVENTS, IORING_FEAT_NODROP, IORING_OFF_CQ_RING, IORING_OFF_SQ_RING, - IORING_OFF_SQES, IOSQE_IO_LINK, io_uring_cqe, io_uring_enter, io_uring_params, - io_uring_setup, io_uring_sqe, + IORING_OFF_SQES, IORING_SETUP_COOP_TASKRUN, IORING_SETUP_DEFER_TASKRUN, + IORING_SETUP_SINGLE_ISSUER, IORING_SETUP_SUBMIT_ALL, IOSQE_IO_LINK, io_uring_cqe, + io_uring_enter, io_uring_params, io_uring_setup, io_uring_sqe, }, }, utils::{ @@ -98,10 +99,29 @@ impl Drop for IoUring { impl IoUring { pub fn new(eng: &Rc, entries: u32) -> Result, IoUringError> { - let mut params = io_uring_params::default(); - let fd = match io_uring_setup(entries, &mut params) { - Ok(f) => f, - Err(e) => return Err(IoUringError::CreateUring(e)), + let feature_levels = [ + IORING_SETUP_SUBMIT_ALL, // 5.18 + IORING_SETUP_COOP_TASKRUN, // 5.19 + IORING_SETUP_SINGLE_ISSUER, // 6.0 + IORING_SETUP_DEFER_TASKRUN, // 6.1 + ]; + let mut feature_levels = &feature_levels[..]; + let mut params; + let fd = loop { + params = io_uring_params::default(); + for &flags in feature_levels { + params.flags |= flags; + } + match io_uring_setup(entries, &mut params) { + Ok(f) => break f, + Err(e) => { + if let Some((_, levels)) = feature_levels.split_last() { + feature_levels = levels; + } else { + return Err(IoUringError::CreateUring(e)); + } + } + } }; if !params.features.contains(IORING_FEAT_NODROP) { return Err(IoUringError::NoDrop); diff --git a/src/io_uring/sys.rs b/src/io_uring/sys.rs index 4666670a..d9ba4197 100644 --- a/src/io_uring/sys.rs +++ b/src/io_uring/sys.rs @@ -102,6 +102,17 @@ pub const IORING_SETUP_CQSIZE: u32 = 1 << 3; pub const IORING_SETUP_CLAMP: u32 = 1 << 4; pub const IORING_SETUP_ATTACH_WQ: u32 = 1 << 5; pub const IORING_SETUP_R_DISABLED: u32 = 1 << 6; +pub const IORING_SETUP_SUBMIT_ALL: u32 = 1 << 7; +pub const IORING_SETUP_COOP_TASKRUN: u32 = 1 << 8; +pub const IORING_SETUP_TASKRUN_FLAG: u32 = 1 << 9; +pub const IORING_SETUP_SQE128: u32 = 1 << 10; +pub const IORING_SETUP_CQE32: u32 = 1 << 11; +pub const IORING_SETUP_SINGLE_ISSUER: u32 = 1 << 12; +pub const IORING_SETUP_DEFER_TASKRUN: u32 = 1 << 13; +pub const IORING_SETUP_NO_MMAP: u32 = 1 << 14; +pub const IORING_SETUP_REGISTERED_FD_ONLY: u32 = 1 << 15; +pub const IORING_SETUP_NO_SQARRAY: u32 = 1 << 16; +pub const IORING_SETUP_HYBRID_IOPOLL: u32 = 1 << 17; pub const IORING_OP_NOP: u8 = 0; pub const IORING_OP_READV: u8 = 1;