Add support for `TagSet` flags by introducing a `Flags` type and adding a flags parameter to `TagSet::new`. This allows configuring tagset behavior such as blocking vs non-blocking operation. The Flags type supports bitwise operations and provides values like `Blocking` for common use cases. The module documentation example is updated to demonstrate the new API. For now, only a single flag is added. Reviewed-by: Alice Ryhl Signed-off-by: Andreas Hindborg --- drivers/block/rnull/rnull.rs | 5 ++++- rust/kernel/block/mq.rs | 6 +++--- rust/kernel/block/mq/tag_set.rs | 13 ++++++++++--- rust/kernel/block/mq/tag_set/flags.rs | 21 +++++++++++++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index 3e7a47e6d0e5..746ddadd11f0 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -128,7 +128,10 @@ fn new( irq_mode: IRQMode, completion_time: Delta, ) -> Result> { - let tagset = Arc::pin_init(TagSet::new(1, 256, 1), GFP_KERNEL)?; + let tagset = Arc::pin_init( + TagSet::new(1, 256, 1, mq::tag_set::Flags::default()), + GFP_KERNEL, + )?; let queue_data = Box::new( QueueData { diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs index 23660817df29..e556b3bb1191 100644 --- a/rust/kernel/block/mq.rs +++ b/rust/kernel/block/mq.rs @@ -57,7 +57,7 @@ //! //! ```rust //! use kernel::{ -//! block::mq::*, +//! block::mq::{self, *}, //! new_mutex, //! prelude::*, //! sync::{aref::ARef, Arc, Mutex}, @@ -92,7 +92,7 @@ //! } //! //! let tagset: Arc> = -//! Arc::pin_init(TagSet::new(1, 256, 1), GFP_KERNEL)?; +//! Arc::pin_init(TagSet::new(1, 256, 1, mq::tag_set::Flags::default()), GFP_KERNEL)?; //! let mut disk = gen_disk::GenDiskBuilder::new() //! .capacity_sectors(4096) //! .build(fmt!("myblk"), tagset, ())?; @@ -103,7 +103,7 @@ pub mod gen_disk; mod operations; mod request; -mod tag_set; +pub mod tag_set; pub use operations::Operations; pub use request::{ diff --git a/rust/kernel/block/mq/tag_set.rs b/rust/kernel/block/mq/tag_set.rs index ec5cac48b83f..5b1a5bcc978d 100644 --- a/rust/kernel/block/mq/tag_set.rs +++ b/rust/kernel/block/mq/tag_set.rs @@ -17,7 +17,7 @@ self, Result, // }, - prelude::try_pin_init, + prelude::*, types::Opaque, }; use core::{ @@ -30,6 +30,12 @@ PinInit, // }; +mod flags; +pub use flags::{ + Flag, + Flags, // +}; + /// A wrapper for the C `struct blk_mq_tag_set`. /// /// `struct blk_mq_tag_set` contains a `struct list_head` and so must be pinned. @@ -51,6 +57,7 @@ pub fn new( nr_hw_queues: u32, num_tags: u32, num_maps: u32, + flags: Flags, ) -> impl PinInit { let tag_set: bindings::blk_mq_tag_set = pin_init::zeroed(); let tag_set: Result<_> = size_of::>() @@ -63,8 +70,8 @@ pub fn new( numa_node: bindings::NUMA_NO_NODE, queue_depth: num_tags, cmd_size, - flags: 0, - driver_data: core::ptr::null_mut::(), + flags: flags.into(), + driver_data: core::ptr::null_mut::(), nr_maps: num_maps, ..tag_set } diff --git a/rust/kernel/block/mq/tag_set/flags.rs b/rust/kernel/block/mq/tag_set/flags.rs new file mode 100644 index 000000000000..b7eaccd200a2 --- /dev/null +++ b/rust/kernel/block/mq/tag_set/flags.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 + +use crate::{ + bindings, + impl_flags, // +}; + +impl_flags! { + /// Flags to be used when creating [`super::TagSet`] objects. + #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)] + pub struct Flags(u32); + + /// Allowed values for [`Flags`]. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub enum Flag { + /// Indicate that the queues associated with this tag set might sleep when + /// processing IO. When this flag is not set, IO is processed in atomic + /// context. When this flag is set, IO is processed in process context. + Blocking = bindings::BLK_MQ_F_BLOCKING, + } +} -- 2.51.2