When exporting a NVMe drive or other high perf multiqueue enabled
devices we may want to pass commands from the guest to the physical
device without been throttled for artificial device wide limits. To
allow the user to tell virtio-scsi that we don't have a LU wide
command limit, this patch uses U32_MAX as a special cmd_per_lun value.

If U32_MAX is used for cmd_per_lun, virtio-scsi will set
SCSI_UNLIMITED_CMD_PER_LUN for the scsi_device's queue limit. In this
case there is no scsi_device wide queue limit and we only go by the
the virtqueue limits (virtqueue limit is translated to scsi host
can_queue which is translated to block layer per hardware queue limit).

There's a small chance of regression where an existing user could be
using U32_MAX and we have been setting the cmd_per_lun to can_queue.
However, I think in the cases the user was doing this, they will want
the new behavior where they are only limited by can_queue because
they have been trying to get the highest queue value possible.

Signed-off-by: Mike Christie <[email protected]>
---
 drivers/scsi/virtio_scsi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 0ed8558dad72..9b31f613ad7e 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -953,7 +953,10 @@ static int virtscsi_probe(struct virtio_device *vdev)
        shost->can_queue = virtqueue_get_vring_size(vscsi->req_vqs[0].vq);
 
        cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1;
-       shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue);
+       if (cmd_per_lun == U32_MAX)
+               shost->cmd_per_lun = SCSI_UNLIMITED_CMD_PER_LUN;
+       else
+               shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue);
        shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF;
 
        /* LUNs > 256 are reported with format 1, so they go in the range
-- 
2.47.1


Reply via email to