diff mbox series

[QEMU,1/3] virtio-scsi-pci: introduce auto-num-queues property

Message ID 169122184935.7839.16786323109706183366-1@git.sr.ht
State New
Headers show
Series provide a smooth upgrade solution for multi-queues disk | expand

Commit Message

~hyman Aug. 5, 2023, 2:33 a.m. UTC
From: Hyman Huang(黄勇) <yong.huang@smartx.com>

Commit "6a55882284 virtio-scsi-pci: default num_queues to -smp N"
implment sizing the number of virtio-scsi-pci request virtqueues
to match the number of vCPUs automatically. Which improves IO
preformance remarkably.

To enable this feature for the existing VMs, the cloud platform
may migrate VMs from the source hypervisor (num_queues is set to
1 by default) to the destination hypervisor (num_queues is set to
-smp N) lively. The different num-queues for virtio-scsi-pci
devices between the source side and the destination side will
result in migration failure due to loading vmstate incorrectly
on the destination side.

To provide a smooth upgrade solution, introduce the
auto-num-queues property for the virtio-scsi-pci device. This
allows upper APPs, e.g., libvirt, to recognize the hypervisor's
capability of allocating the virtqueues automatically by probing
the virtio-scsi-pci.auto-num-queues property. Basing on which,
upper APPs can ensure to allocate the same num-queues on the
destination side in case of migration failure.

Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
---
 hw/scsi/vhost-scsi.c            |  2 ++
 hw/scsi/vhost-user-scsi.c       |  2 ++
 hw/scsi/virtio-scsi.c           |  2 ++
 hw/virtio/vhost-scsi-pci.c      | 11 +++++++++--
 hw/virtio/vhost-user-scsi-pci.c | 11 +++++++++--
 hw/virtio/virtio-scsi-pci.c     | 11 +++++++++--
 include/hw/virtio/virtio-scsi.h |  5 +++++
 7 files changed, 38 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 443f67daa4..78a8929c49 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -284,6 +284,8 @@  static Property vhost_scsi_properties[] = {
     DEFINE_PROP_STRING("vhostfd", VirtIOSCSICommon, conf.vhostfd),
     DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn),
     DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
+    DEFINE_PROP_BOOL("auto_num_queues", VirtIOSCSICommon, auto_num_queues,
+                     true),
     DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
                        VIRTIO_SCSI_AUTO_NUM_QUEUES),
     DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSICommon, conf.virtqueue_size,
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index ee99b19e7a..1b837f370a 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -161,6 +161,8 @@  static void vhost_user_scsi_unrealize(DeviceState *dev)
 static Property vhost_user_scsi_properties[] = {
     DEFINE_PROP_CHR("chardev", VirtIOSCSICommon, conf.chardev),
     DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
+    DEFINE_PROP_BOOL("auto_num_queues", VirtIOSCSICommon, auto_num_queues,
+                     true),
     DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
                        VIRTIO_SCSI_AUTO_NUM_QUEUES),
     DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSICommon, conf.virtqueue_size,
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 45b95ea070..2ec13032aa 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -1279,6 +1279,8 @@  static void virtio_scsi_device_unrealize(DeviceState *dev)
 }
 
 static Property virtio_scsi_properties[] = {
+    DEFINE_PROP_BOOL("auto_num_queues", VirtIOSCSI, parent_obj.auto_num_queues,
+                     true),
     DEFINE_PROP_UINT32("num_queues", VirtIOSCSI, parent_obj.conf.num_queues,
                        VIRTIO_SCSI_AUTO_NUM_QUEUES),
     DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSI,
diff --git a/hw/virtio/vhost-scsi-pci.c b/hw/virtio/vhost-scsi-pci.c
index 08980bc23b..927c155278 100644
--- a/hw/virtio/vhost-scsi-pci.c
+++ b/hw/virtio/vhost-scsi-pci.c
@@ -51,8 +51,15 @@  static void vhost_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     VirtIOSCSIConf *conf = &dev->vdev.parent_obj.parent_obj.conf;
 
     if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
-        conf->num_queues =
-            virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
+        /*
+         * Allocate virtqueues automatically only if auto_num_queues
+         * property set true.
+         */
+        if (dev->vdev.parent_obj.parent_obj.auto_num_queues)
+            conf->num_queues =
+                virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
+        else
+            conf->num_queues = 1;
     }
 
     if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
diff --git a/hw/virtio/vhost-user-scsi-pci.c b/hw/virtio/vhost-user-scsi-pci.c
index 75882e3cf9..9c521a7f93 100644
--- a/hw/virtio/vhost-user-scsi-pci.c
+++ b/hw/virtio/vhost-user-scsi-pci.c
@@ -57,8 +57,15 @@  static void vhost_user_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     VirtIOSCSIConf *conf = &dev->vdev.parent_obj.parent_obj.conf;
 
     if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
-        conf->num_queues =
-            virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
+        /*
+         * Allocate virtqueues automatically only if auto_num_queues
+         * property set true.
+         */
+        if (dev->vdev.parent_obj.parent_obj.auto_num_queues)
+            conf->num_queues =
+                virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
+        else
+            conf->num_queues = 1;
     }
 
     if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
diff --git a/hw/virtio/virtio-scsi-pci.c b/hw/virtio/virtio-scsi-pci.c
index e8e3442f38..7551857f90 100644
--- a/hw/virtio/virtio-scsi-pci.c
+++ b/hw/virtio/virtio-scsi-pci.c
@@ -52,8 +52,15 @@  static void virtio_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     char *bus_name;
 
     if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) {
-        conf->num_queues =
-            virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
+        /*
+         * Allocate virtqueues automatically only if auto_num_queues
+         * property set true.
+         */
+        if (dev->vdev.parent_obj.auto_num_queues)
+            conf->num_queues =
+                virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED);
+        else
+            conf->num_queues = 1;
     }
 
     if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 779568ab5d..2660bbad22 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -72,6 +72,11 @@  struct VirtIOSCSICommon {
     VirtQueue *ctrl_vq;
     VirtQueue *event_vq;
     VirtQueue **cmd_vqs;
+    /*
+     * Set to true if virtqueues allow to be allocated to
+     * match the number of virtual CPUs automatically.
+     */
+    bool auto_num_queues;
 };
 
 struct VirtIOSCSIReq;