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(-) 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 */ -- 2.50.1