From 9ffff2a5461ddc81b670f88ebecb939230a44a5f Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Thu, 4 Apr 2024 10:12:22 +0200 Subject: [PATCH 1/3] Add doc alias to Config::attach_queue --- src/config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.rs b/src/config.rs index 8c708935..c8426ba5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -151,6 +151,7 @@ impl<'r> Config<'r> { } /// Same as [`Config::attach`], but accepts a [`SubmissionQueue`]. + #[doc(alias = "IORING_SETUP_ATTACH_WQ")] pub const fn attach_queue(mut self, other_ring: &'r SubmissionQueue) -> Self { self.attach = Some(other_ring); self From 398cdbdc61e3927895e6b87aabd1680c3af41f4a Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Thu, 4 Apr 2024 10:14:53 +0200 Subject: [PATCH 2/3] Add Config::disable Uses IORING_SETUP_R_DISABLED to start the ring in a disabled state. --- src/config.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/config.rs b/src/config.rs index c8426ba5..9913a1c7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,6 +17,7 @@ use crate::{libc, AtomicBitMap, CompletionQueue, Ring, SharedSubmissionQueue, Su pub struct Config<'r> { submission_entries: u32, completion_entries: Option, + disabled: bool, clamp: bool, kernel_thread: bool, cpu_affinity: Option, @@ -56,6 +57,7 @@ impl<'r> Config<'r> { Config { submission_entries: entries, completion_entries: None, + disabled: false, clamp: false, kernel_thread: true, cpu_affinity: None, @@ -64,6 +66,16 @@ impl<'r> Config<'r> { } } + /// Start the ring in a disabled state. + /// + /// While the ring is disabled submissions are not allowed. To enable the + /// ring use [`Ring::enable`]. + #[doc(alias = "IORING_SETUP_R_DISABLED")] + pub const fn disable(mut self) -> Config<'r> { + self.disabled = true; + self + } + /// Set the size of the completion queue. /// /// By default the kernel will use a completion queue twice as large as the @@ -171,6 +183,9 @@ impl<'r> Config<'r> { // Don't interrupt userspace, the user must call `Ring::poll` any way. parameters.flags |= libc::IORING_SETUP_COOP_TASKRUN; } + if self.disabled { + parameters.flags |= libc::IORING_SETUP_R_DISABLED; + } if let Some(completion_entries) = self.completion_entries { parameters.cq_entries = completion_entries; parameters.flags |= libc::IORING_SETUP_CQSIZE; From 457aa7e3eb9b5f7b03ba6a71e704ea8d13864079 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Thu, 4 Apr 2024 10:21:41 +0200 Subject: [PATCH 3/3] Add Ring::enable To enable a ring started in disabled mode. --- src/lib.rs | 14 ++++++++++++++ tests/ring.rs | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 5454c2d6..e97fb741 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -226,6 +226,20 @@ impl Ring { &self.sq } + /// Enable the ring. + /// + /// This only required when starting the ring in disabled mode, see + /// [`Config::disable`]. + pub fn enable(&mut self) -> io::Result<()> { + libc::syscall!(io_uring_register( + self.sq.shared.ring_fd.as_raw_fd(), + libc::IORING_REGISTER_ENABLE_RINGS, + ptr::null(), + 0, + ))?; + Ok(()) + } + /// Poll the ring for completions. /// /// This will wake all completed [`Future`]s with the result of their diff --git a/tests/ring.rs b/tests/ring.rs index da3e9531..ee4d0a63 100644 --- a/tests/ring.rs +++ b/tests/ring.rs @@ -149,6 +149,20 @@ fn submission_queue_full_is_handle_internally() { } } +#[test] +fn config_disabled() { + init(); + let mut ring = Ring::config(1).disable().build().unwrap(); + + // In a disabled state, so we expect an error. + let err = ring.poll(None).unwrap_err(); + assert_eq!(err.raw_os_error(), Some(libc::EBADFD)); + + // Enabling it should allow us to poll. + ring.enable().unwrap(); + ring.poll(Some(Duration::from_millis(1))).unwrap(); +} + #[test] fn wake_ring() { init();