[PATCH v2 39/83] block: rust: add a request queue abstraction

From: Andreas Hindborg

Date: Tue Jun 09 2026 - 15:29:42 EST


Add the `RequestQueue` type as a Rust abstraction for `struct
request_queue`. This type provides methods to access the request queue
associated with a `GenDisk` or `Request`.

The abstraction exposes queue-related functionality needed by block
device drivers.

Signed-off-by: Andreas Hindborg <a.hindborg@xxxxxxxxxx>
---
rust/kernel/block/mq.rs | 2 ++
rust/kernel/block/mq/gen_disk.rs | 7 ++++
rust/kernel/block/mq/request_queue.rs | 60 +++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+)

diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs
index 77e3593e8626..e89eb394001f 100644
--- a/rust/kernel/block/mq.rs
+++ b/rust/kernel/block/mq.rs
@@ -127,6 +127,7 @@
pub mod gen_disk;
mod operations;
mod request;
+mod request_queue;
pub mod tag_set;

pub use operations::Operations;
@@ -135,4 +136,5 @@
Request,
RequestTimerHandle, //
};
+pub use request_queue::RequestQueue;
pub use tag_set::TagSet;
diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_disk.rs
index f51bccb0d2ef..6ba8d88f63a9 100644
--- a/rust/kernel/block/mq/gen_disk.rs
+++ b/rust/kernel/block/mq/gen_disk.rs
@@ -9,6 +9,7 @@
bindings,
block::mq::{
Operations,
+ RequestQueue,
TagSet, //
},
error::{
@@ -253,6 +254,12 @@ impl<T: Operations> GenDisk<T> {
pub fn get_ref(&self) -> Arc<Revocable<GenDiskRef<T>>> {
self.backref.clone()
}
+
+ /// Get the [`RequestQueue`] associated with this [`GenDisk`].
+ pub fn queue(&self) -> &RequestQueue<T> {
+ // SAFETY: By type invariant, self is a valid gendisk.
+ unsafe { RequestQueue::from_raw((*self.gendisk).queue) }
+ }
}

// SAFETY: `GenDisk` is an owned pointer to a `struct gendisk` and an `Arc` to a
diff --git a/rust/kernel/block/mq/request_queue.rs b/rust/kernel/block/mq/request_queue.rs
new file mode 100644
index 000000000000..45fb55b1a310
--- /dev/null
+++ b/rust/kernel/block/mq/request_queue.rs
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use super::Operations;
+use crate::types::{
+ ForeignOwnable,
+ Opaque, //
+};
+use core::marker::PhantomData;
+
+/// A structure describing the queues associated with a block device.
+///
+/// Owned by a [`GenDisk`].
+///
+/// # Invariants
+///
+/// - `self.0` is a valid `bindings::request_queue`.
+/// - `self.0.queuedata` is a valid `T::QueueData`.
+#[repr(transparent)]
+pub struct RequestQueue<T>(Opaque<bindings::request_queue>, PhantomData<T>);
+
+impl<T> RequestQueue<T>
+where
+ T: Operations,
+{
+ /// Create a [`RequestQueue`] from a raw `bindings::request_queue` pointer
+ ///
+ /// # Safety
+ ///
+ /// - `ptr` must be valid for use as a reference for the duration of `'a`.
+ /// - `ptr` must have been initialized as part of [`GenDiskBuilder::build`].
+ pub(crate) unsafe fn from_raw<'a>(ptr: *const bindings::request_queue) -> &'a Self {
+ // INVARIANT:
+ // - By function safety requirements, `ptr` is a valid `request_queue`.
+ // - By function safety requirement `ptr` was initialized by [`GenDiskBuilder::build`], and
+ // thus `queuedata` was set to point to a valid `T::QueueData`.
+ //
+ // SAFETY: By function safety requirements `ptr` is valid for use as a reference.
+ unsafe { &*ptr.cast() }
+ }
+
+ /// Get the driver private data associated with this [`RequestQueue`].
+ pub fn queue_data(&self) -> <T::QueueData as ForeignOwnable>::Borrowed<'_> {
+ // SAFETY: By type invariant, `queuedata` is a valid `T::QueueData`.
+ unsafe { T::QueueData::borrow((*self.0.get()).queuedata) }
+ }
+
+ /// Stop all hardware queues of this [`RequestQueue`].
+ pub fn stop_hw_queues(&self) {
+ // SAFETY: By type invariant, `self.0` is a valid `request_queue`.
+ unsafe { bindings::blk_mq_stop_hw_queues(self.0.get()) }
+ }
+
+ /// Start all hardware queues of this [`RequestQueue`].
+ ///
+ /// This function will mark the queues as ready and if necessary, schedule the queues to run.
+ pub fn start_stopped_hw_queues_async(&self) {
+ // SAFETY: By type invariant, `self.0` is a valid `request_queue`.
+ unsafe { bindings::blk_mq_start_stopped_hw_queues(self.0.get(), true) }
+ }
+}

--
2.51.2