Add ability to set the number of hardware queues. The default value remains the number of CPUs. This functionality is useful in some environments (e.g. Microsoft Azure) when decreasing the number of hardware queues has been shown to improve performance. Signed-off-by: Melanie Plageman (Microsoft) <melanieplageman@xxxxxxxxx> --- drivers/scsi/storvsc_drv.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 2e4fa77445fd..d72ab6daf9ae 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -378,10 +378,14 @@ static u32 max_outstanding_req_per_channel; static int storvsc_change_queue_depth(struct scsi_device *sdev, int queue_depth); static int storvsc_vcpus_per_sub_channel = 4; +static int storvsc_nr_hw_queues = -1; module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); +module_param(storvsc_nr_hw_queues, int, S_IRUGO); +MODULE_PARM_DESC(storvsc_nr_hw_queues, "Number of hardware queues"); + module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO); MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels"); @@ -2004,8 +2008,12 @@ static int storvsc_probe(struct hv_device *device, * For non-IDE disks, the host supports multiple channels. * Set the number of HW queues we are supporting. */ - if (!dev_is_ide) - host->nr_hw_queues = num_present_cpus(); + if (!dev_is_ide) { + if (storvsc_nr_hw_queues == -1) + host->nr_hw_queues = num_present_cpus(); + else + host->nr_hw_queues = storvsc_nr_hw_queues; + } /* * Set the error handler work queue. @@ -2155,6 +2163,7 @@ static struct fc_function_template fc_transport_functions = { static int __init storvsc_drv_init(void) { int ret; + int ncpus = num_present_cpus(); /* * Divide the ring buffer data size (which is 1 page less @@ -2169,6 +2178,14 @@ static int __init storvsc_drv_init(void) vmscsi_size_delta, sizeof(u64))); + if (storvsc_nr_hw_queues > ncpus || storvsc_nr_hw_queues == 0 || + storvsc_nr_hw_queues < -1) { + printk(KERN_ERR "storvsc: Invalid storvsc_nr_hw_queues value of %d. + Valid values include -1 and 1-%d.\n", + storvsc_nr_hw_queues, ncpus); + return -EINVAL; + } + #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) fc_transport_template = fc_attach_transport(&fc_transport_functions); if (!fc_transport_template) -- 2.20.1