[PATCH v2 09/11] qemu: Implement support for iothread <-> virtqueue mapping for 'virtio-scsi' controllers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Similarly to 'virtio-blk' users can map multiple iothreads and pin them
appropriately for 'virtio-scsi' controllers to ensure the best
performance.

Implement the validation and command line generation based on the
helpers we have for 'virtio-blk'.

Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx>
---
 src/qemu/qemu_command.c  | 22 ++++++++++++++++++++++
 src/qemu/qemu_command.h  |  2 ++
 src/qemu/qemu_validate.c | 34 +++++++++++++++++++++++++++-------
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 14d62b98e4..fc0712f836 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1657,6 +1657,15 @@ qemuCommandGetVirtioIothreadMapVirtioBlk(const virDomainDiskDef *disk)
 }


+GHashTable *
+qemuCommandGetVirtioIothreadMapVirtioSCSI(const virDomainControllerDef *def)
+{
+    const char *internal_queues[] = { "ctrl", "event", NULL };
+
+    return qemuCommandGetVirtioIothreadMap(def->queues, internal_queues);
+}
+
+
 virJSONValue *
 qemuBuildDiskDeviceProps(const virDomainDef *def,
                          virDomainDiskDef *disk,
@@ -2558,6 +2567,7 @@ qemuBuildControllerSCSIDevProps(virDomainControllerDef *def,
                                 virQEMUCaps *qemuCaps)
 {
     g_autoptr(virJSONValue) props = NULL;
+    g_autoptr(virJSONValue) iothreadsMapping = NULL;
     g_autofree char *iothread = NULL;
     const char *driver = NULL;

@@ -2569,6 +2579,17 @@ qemuBuildControllerSCSIDevProps(virDomainControllerDef *def,
                                               qemuCaps)))
             return NULL;

+        if (def->iothreads) {
+            g_autoptr(GHashTable) queueMap = NULL;
+
+            if (def->queues > 0)
+                queueMap = qemuCommandGetVirtioIothreadMapVirtioSCSI(def);
+
+            if (!(iothreadsMapping = qemuBuildIothreadMappingProps(def->iothreads,
+                                                                   queueMap)))
+                return NULL;
+        }
+
         if (def->iothread > 0)
             iothread = g_strdup_printf("iothread%u", def->iothread);

@@ -2576,6 +2597,7 @@ qemuBuildControllerSCSIDevProps(virDomainControllerDef *def,
                                   "S:iothread", iothread,
                                   "s:id", def->info.alias,
                                   "p:num_queues", def->queues,
+                                  "A:iothread-vq-mapping", &iothreadsMapping,
                                   "p:cmd_per_lun", def->cmd_per_lun,
                                   "p:max_sectors", def->max_sectors,
                                   "T:ioeventfd", def->ioeventfd,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 636c2571d4..d69fd793c4 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -280,3 +280,5 @@ struct qemuVirtioIothreadMap {

 GHashTable *
 qemuCommandGetVirtioIothreadMapVirtioBlk(const virDomainDiskDef *disk);
+GHashTable *
+qemuCommandGetVirtioIothreadMapVirtioSCSI(const virDomainControllerDef *def);
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index f8586a7dff..364bc59cba 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -3641,9 +3641,10 @@ qemuValidateDomainDeviceDefControllerIDE(const virDomainControllerDef *controlle
  */
 static int
 qemuValidateCheckSCSIControllerIOThreads(const virDomainControllerDef *controller,
-                                         const virDomainDef *def)
+                                         const virDomainDef *def,
+                                         virQEMUCaps *qemuCaps)
 {
-    if (!controller->iothread)
+    if (controller->iothread == 0 && !controller->iothreads)
         return 0;

     if (controller->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
@@ -3654,8 +3655,24 @@ qemuValidateCheckSCSIControllerIOThreads(const virDomainControllerDef *controlle
        return -1;
     }

-    /* Can we find the controller iothread in the iothreadid list? */
-    if (!virDomainIOThreadIDFind(def, controller->iothread)) {
+    if (controller->iothreads) {
+        g_autoptr(GHashTable) queueMap = NULL;
+
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("IOThread mapping for virtio-scsi controllers is not available with this QEMU binary"));
+            return -1;
+        }
+
+        if (controller->queues > 0)
+            queueMap = qemuCommandGetVirtioIothreadMapVirtioSCSI(controller);
+
+        if (qemuDomainValidateIothreadMapping(def, controller->iothreads, queueMap) < 0)
+            return -1;
+    }
+
+    if (controller->iothread > 0 &&
+        !virDomainIOThreadIDFind(def, controller->iothread)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("controller iothread '%1$u' not defined in iothreadid"),
                        controller->iothread);
@@ -3668,13 +3685,15 @@ qemuValidateCheckSCSIControllerIOThreads(const virDomainControllerDef *controlle

 static int
 qemuValidateDomainDeviceDefControllerSCSI(const virDomainControllerDef *controller,
-                                          const virDomainDef *def)
+                                          const virDomainDef *def,
+                                          virQEMUCaps *qemuCaps)
 {
     switch ((virDomainControllerModelSCSI) controller->model) {
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL:
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL:
-            if (qemuValidateCheckSCSIControllerIOThreads(controller, def) < 0)
+            if (qemuValidateCheckSCSIControllerIOThreads(controller, def,
+                                                         qemuCaps) < 0)
                 return -1;
             break;

@@ -4348,7 +4367,8 @@ qemuValidateDomainDeviceDefController(const virDomainControllerDef *controller,
         break;

     case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
-        ret = qemuValidateDomainDeviceDefControllerSCSI(controller, def);
+        ret = qemuValidateDomainDeviceDefControllerSCSI(controller, def,
+                                                        qemuCaps);
         break;

     case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
-- 
2.48.1




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux