summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongli Zhang <dongli.zhang@oracle.com>2026-08-02 10:24:56 -0700
committerMichael S. Tsirkin <mst@redhat.com>2026-09-07 18:54:04 -0400
commit4e3ec5b1b427e02082e8b3491731f8c3bcf85c53 (patch)
tree1b24b448c6d44a0c1fabd97e9d17bc563bd41c25
parentc952e607cb4aa3640e5ae07243d3f609dac94424 (diff)
vhost-scsi: clamp max_io_vqs module parameter
max_io_vqs is currently validated only when a vhost-scsi device is opened. This allows sysfs to show values larger than the driver will actually use, e.g. writing 2048 succeeds even though vhost_scsi_open() later clamps it to VHOST_SCSI_MAX_IO_VQ. This makes the sysfs value differ from the value that will actually be used. hv# echo 2048 > /sys/module/vhost_scsi/parameters/max_io_vqs hv# cat /sys/module/vhost_scsi/parameters/max_io_vqs 2048 [ 315.630495] Invalid max_io_vqs of 2048. Using 1024. Keep accepting out-of-range values for compatibility, but clamp them in the module parameter setter and store the effective value. This preserves the existing behavior that invalid values do not make module loading or sysfs writes fail. It also makes reads report the value that will actually be used. With the parameter value kept in range, remove the duplicate validation from vhost_scsi_open(). Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com> Reviewed-by: Mike Christie <michael.christie@oracle.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260802172534.260047-3-dongli.zhang@oracle.com>
-rw-r--r--drivers/vhost/scsi.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 223549313ce9..4f8c0260bc9e 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -210,7 +210,37 @@ static const int vhost_scsi_bits[] = {
#define VHOST_SCSI_MAX_EVENT 128
static unsigned vhost_scsi_max_io_vqs = 128;
-module_param_named(max_io_vqs, vhost_scsi_max_io_vqs, uint, 0644);
+
+static int vhost_scsi_set_max_io_vqs(const char *val,
+ const struct kernel_param *kp)
+{
+ unsigned int max_io_vqs;
+ int ret;
+
+ ret = kstrtouint(val, 0, &max_io_vqs);
+ if (ret)
+ return ret;
+
+ if (max_io_vqs > VHOST_SCSI_MAX_IO_VQ) {
+ pr_err("Invalid max_io_vqs of %u. Using %u.\n",
+ max_io_vqs, VHOST_SCSI_MAX_IO_VQ);
+ max_io_vqs = VHOST_SCSI_MAX_IO_VQ;
+ } else if (!max_io_vqs) {
+ pr_err("Invalid max_io_vqs of 0. Using 1.\n");
+ max_io_vqs = 1;
+ }
+
+ WRITE_ONCE(vhost_scsi_max_io_vqs, max_io_vqs);
+ return 0;
+}
+
+static const struct kernel_param_ops vhost_scsi_max_io_vqs_op = {
+ .set = vhost_scsi_set_max_io_vqs,
+ .get = param_get_uint,
+};
+
+module_param_cb(max_io_vqs, &vhost_scsi_max_io_vqs_op,
+ &vhost_scsi_max_io_vqs, 0644);
MODULE_PARM_DESC(max_io_vqs, "Set the max number of IO virtqueues a vhost scsi device can support. The default is 128. The max is 1024.");
struct vhost_scsi_virtqueue {
@@ -2290,21 +2320,14 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
struct vhost_scsi_virtqueue *svq;
struct vhost_scsi *vs;
struct vhost_virtqueue **vqs;
- int r = -ENOMEM, i, nvqs = vhost_scsi_max_io_vqs;
+ int r = -ENOMEM, i, nvqs;
vs = kvzalloc_obj(*vs);
if (!vs)
goto err_vs;
vs->inline_sg_cnt = vhost_scsi_inline_sg_cnt;
- if (nvqs > VHOST_SCSI_MAX_IO_VQ) {
- pr_err("Invalid max_io_vqs of %d. Using %d.\n", nvqs,
- VHOST_SCSI_MAX_IO_VQ);
- nvqs = VHOST_SCSI_MAX_IO_VQ;
- } else if (nvqs == 0) {
- pr_err("Invalid max_io_vqs of %d. Using 1.\n", nvqs);
- nvqs = 1;
- }
+ nvqs = READ_ONCE(vhost_scsi_max_io_vqs);
nvqs += VHOST_SCSI_VQ_IO;
vs->old_inflight = kmalloc_objs(*vs->old_inflight, nvqs,