[PATCH 78/79] block: rnull: add `shared_tag_bitmap` config option

From: Andreas Hindborg

Date: Sun Feb 15 2026 - 18:53:48 EST


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 <a.hindborg@xxxxxxxxxx>
---
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<FaultConfig>,
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<Self, Error> {
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<FaultConfig>,
max_sectors: u32,
virt_boundary: bool,
+ shared_tag_bitmap: bool,
}

static SHARED_TAG_SET: SetOnce<Arc<TagSet<NullBlkDevice>>> = SetOnce::new();
@@ -425,6 +431,7 @@ fn new(options: NullBlkOptions<'_>) -> Result<Arc<GenDisk<Self>>> {
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<Arc<GenDisk<Self>>> {
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