Add a configfs attribute and module parameter to enable the `BLK_MQ_F_TAG_HCTX_SHARED` flag for the rnull tag set. When enabled, a tag bitmap is shared across all hardware queues. Signed-off-by: Andreas Hindborg --- drivers/block/rnull/configfs.rs | 5 +++++ drivers/block/rnull/rnull.rs | 11 +++++++++++ rust/kernel/block/mq/tag_set/flags.rs | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs index 8b9ad8a1a243b..395da68d96dc6 100644 --- a/drivers/block/rnull/configfs.rs +++ b/drivers/block/rnull/configfs.rs @@ -124,6 +124,7 @@ fn make_group( fua: 28, max_sectors: 29, virt_boundary: 30, + shared_tag_bitmap: 31, ], }; @@ -212,6 +213,7 @@ fn make_group( init_hctx_inject, max_sectors: 0, virt_boundary: false, + shared_tag_bitmap: false, }), }), default_groups, @@ -296,6 +298,7 @@ struct DeviceConfigInner { init_hctx_inject: Arc, max_sectors: u32, virt_boundary: bool, + shared_tag_bitmap: bool, } #[vtable] @@ -355,6 +358,7 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result { timeout_inject: guard.timeout_inject.clone(), max_sectors: guard.max_sectors, virt_boundary: guard.virt_boundary, + shared_tag_bitmap: guard.shared_tag_bitmap, })?); guard.powered = true; } else if guard.powered && !power_op { @@ -634,3 +638,4 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result { configfs_simple_bool_field!(DeviceConfig, 28, fua); configfs_simple_field!(DeviceConfig, 29, max_sectors, u32); configfs_simple_bool_field!(DeviceConfig, 30, virt_boundary); +configfs_simple_bool_field!(DeviceConfig, 31, shared_tag_bitmap); diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index dfdb56bd76f52..5bf965908ef63 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -218,6 +218,10 @@ default: 0, description: "Set alignment requirement for IO buffers to be page size.", }, + shared_tag_bitmap: u8 { + default: 0, + description: "Use shared tag bitmap for all submission queues for blk-mq.", + }, }, } @@ -296,6 +300,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit { timeout_inject: Arc::pin_init(FaultConfig::new(c"timeout_inject"), GFP_KERNEL)?, max_sectors: *module_parameters::max_sectors.value(), virt_boundary: *module_parameters::virt_boundary.value() != 0, + shared_tag_bitmap: *module_parameters::shared_tag_bitmap.value() != 0, })?; disks.push(disk, GFP_KERNEL)?; } @@ -352,6 +357,7 @@ struct NullBlkOptions<'a> { timeout_inject: Arc, max_sectors: u32, virt_boundary: bool, + shared_tag_bitmap: bool, } static SHARED_TAG_SET: SetOnce>> = SetOnce::new(); @@ -425,6 +431,7 @@ fn new(options: NullBlkOptions<'_>) -> Result>> { timeout_inject, max_sectors, virt_boundary, + shared_tag_bitmap, } = options; let mut flags = mq::tag_set::Flags::default(); @@ -437,6 +444,10 @@ fn new(options: NullBlkOptions<'_>) -> Result>> { flags |= mq::tag_set::Flag::NoDefaultScheduler; } + if shared_tag_bitmap { + flags |= mq::tag_set::Flag::TagHctxShared; + } + if home_node > kernel::num_online_nodes().try_into()? { return Err(code::EINVAL); } diff --git a/rust/kernel/block/mq/tag_set/flags.rs b/rust/kernel/block/mq/tag_set/flags.rs index 1fca4fcb4dd20..cc5f54781cfd8 100644 --- a/rust/kernel/block/mq/tag_set/flags.rs +++ b/rust/kernel/block/mq/tag_set/flags.rs @@ -19,5 +19,9 @@ pub enum Flag { /// Select 'none' during queue registration in case of a single hwq or shared /// hwqs instead of 'mq-deadline'. NoDefaultScheduler = bindings::BLK_MQ_F_NO_SCHED_BY_DEFAULT, + + /// Use shared tag bitmap for all submission queues. + TagHctxShared = bindings::BLK_MQ_F_TAG_HCTX_SHARED, + } } -- 2.51.2