在 2025/07/23 21:43, Nilay Shroff 写道:
When a user updates the number of submit or poll queues on a null_blk
device, the block layer creates new hardware queues (hctxs). However, if
the device is using a shared tagset, null_blk does not map any software
queues (ctx) to the newly created hctx (via null_map_queues()), resulting
in those hardware queues being left unused for I/O. This behavior is
misleading, as the user may expect the new queues to be functional, even
though they are effectively ignored. To avoid this confusion and potential
misconfiguration:
- Reject runtime updates to submit_queues or poll_queues via sysfs when
the device uses a shared tagset by returning -EINVAL.
- During configuration validation (prior to powering on the device), reset
submit_queues and poll_queues to the module parameters (g_submit_queues
and g_poll_queues) if the shared tagset is enabled.
This ensures consistent behavior and avoids creating unused hardware queues
(hctxs) due to ineffective runtime queue updates.
Signed-off-by: Nilay Shroff <nilay@xxxxxxxxxxxxx>
---
drivers/block/null_blk/main.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
Reviewed-by: Yu Kuai <yukuai3@xxxxxxxxxx>
Thanks
diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
index aa163ae9b2aa..57bd9aeb9aaf 100644
--- a/drivers/block/null_blk/main.c
+++ b/drivers/block/null_blk/main.c
@@ -388,6 +388,12 @@ static int nullb_update_nr_hw_queues(struct nullb_device *dev,
if (!submit_queues)
return -EINVAL;
+ /*
+ * Cannot update queues with shared tagset.
+ */
+ if (dev->shared_tags)
+ return -EINVAL;
+
/*
* Make sure that null_init_hctx() does not access nullb->queues[] past
* the end of that array.
@@ -1884,18 +1890,24 @@ static int null_validate_conf(struct nullb_device *dev)
dev->queue_mode = NULL_Q_MQ;
}
- if (dev->use_per_node_hctx) {
- if (dev->submit_queues != nr_online_nodes)
- dev->submit_queues = nr_online_nodes;
- } else if (dev->submit_queues > nr_cpu_ids)
- dev->submit_queues = nr_cpu_ids;
- else if (dev->submit_queues == 0)
- dev->submit_queues = 1;
- dev->prev_submit_queues = dev->submit_queues;
-
- if (dev->poll_queues > g_poll_queues)
+ if (dev->shared_tags) {
+ dev->submit_queues = g_submit_queues;
dev->poll_queues = g_poll_queues;
+ } else {
+ if (dev->use_per_node_hctx) {
+ if (dev->submit_queues != nr_online_nodes)
+ dev->submit_queues = nr_online_nodes;
+ } else if (dev->submit_queues > nr_cpu_ids)
+ dev->submit_queues = nr_cpu_ids;
+ else if (dev->submit_queues == 0)
+ dev->submit_queues = 1;
+
+ if (dev->poll_queues > g_poll_queues)
+ dev->poll_queues = g_poll_queues;
+ }
+ dev->prev_submit_queues = dev->submit_queues;
dev->prev_poll_queues = dev->poll_queues;
+
dev->irqmode = min_t(unsigned int, dev->irqmode, NULL_IRQ_TIMER);
/* Do memory allocation, so set blocking */