[PATCH v2 08/11] conf: Add support for iothread to queue mapping config for 'virtio-scsi'

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

 



Upcoming qemu release will support configuring mapping iothreads to
virtio queues for 'virtio-scsi' controllers in order to improve
performance.

Reuse the infrastructure we have from the same configuration for
'virti-blk' to implement the conf support for this feature.

Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx>
---
 docs/formatdomain.rst             | 41 +++++++++++++++++++++++++++++++
 src/conf/domain_conf.c            | 10 +++++++-
 src/conf/domain_conf.h            |  1 +
 src/conf/domain_validate.c        | 10 +++++++-
 src/conf/schemas/domaincommon.rng |  9 ++++++-
 src/hypervisor/domain_driver.c    |  3 ++-
 6 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 29f3c84780..d049f28a65 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -4146,6 +4146,47 @@ An optional sub-element ``driver`` can specify the driver specific options:
    If a specific IOThread is desired for a specific SCSI ``disk``, then multiple
    controllers must be defined each having a specific ``iothread`` value. The
    ``iothread`` value must be within the range 1 to the domain iothreads value.
+``iothreads``
+   Supported for ``virtio-scsi`` controllers using ``address`` types ``pci`` and
+   ``ccw``. :since:`since 11.2.0 (QEMU 10.0).` Mutually exclusive with ``iothread``.
+
+   The optional ``iothreads`` sub-element allows specifying multiple IOThreads
+   via the ``iothread`` sub-element with attribute ``id``  the ``virtio-scsi``
+   controller will use for I/O operations. The virt queues (see ``queues``
+   attribute of ``driver``) are automatically distributed among the configured
+   iothreads.
+
+   Optionally the ``iothread`` element can have multiple ``queue`` subelements
+   with mandatory ``id`` atribute specifying that the iothread should be used
+   to handle given virt queue. If queue mapping is present the ``queues``
+   attribute of ``driver`` must be configured and all configured virt queues
+   must be included in the mapping. The ``virtio-scsi`` controller exposes two
+   special queues named ``ctrl`` and ``event`` and request virt queues ``0`` to
+   ``N-1`` where N is the number of queues configured for the device.
+
+      Example::
+
+        <driver queues='4>
+          <iothreads>
+            <iothread id='2'/>
+            <iothread id='3'/>
+          </iothreads>
+        </driver>
+
+        <driver queues='3'>
+          <iothreads>
+            <iothread id='2'>
+              <queue id='ctrl'/>
+              <queue id='event'/>
+              <queue id='1'/>
+            </iothread>
+            <iothread id='3'>
+              <queue id='0'/>
+              <queue id='2'/>
+            </iothread>
+          </iothreads>
+        </driver>
+
 virtio options
    For virtio controllers, `Virtio-related options`_ can
    also be set. ( :since:`Since 3.5.0` )
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index bb82264758..def2ef7ae7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2557,6 +2557,8 @@ void virDomainControllerDefFree(virDomainControllerDef *def)
     if (!def)
         return;

+    g_slist_free_full(def->iothreads, (GDestroyNotify) virDomainIothreadMappingDefFree);
+
     virDomainDeviceInfoClear(&def->info);
     g_free(def->virtio);

@@ -8618,6 +8620,9 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt,
                            &def->iothread) < 0)
             return NULL;

+        if (virDomainIothreadMappingDefParse(driver, &def->iothreads) < 0)
+            return NULL;
+
         if (virDomainVirtioOptionsParseXML(driver, &def->virtio) < 0)
             return NULL;
     }
@@ -23505,6 +23510,7 @@ virDomainControllerDriverFormat(virBuffer *buf,
                                 virDomainControllerDef *def)
 {
     g_auto(virBuffer) driverBuf = VIR_BUFFER_INITIALIZER;
+    g_auto(virBuffer) driverChildBuf = VIR_BUFFER_INIT_CHILD(buf);

     if (def->queues)
         virBufferAsprintf(&driverBuf, " queues='%u'", def->queues);
@@ -23523,9 +23529,11 @@ virDomainControllerDriverFormat(virBuffer *buf,
     if (def->iothread)
         virBufferAsprintf(&driverBuf, " iothread='%u'", def->iothread);

+    virDomainIothreadMappingDefFormat(&driverChildBuf, def->iothreads);
+
     virDomainVirtioOptionsFormat(&driverBuf, def->virtio);

-    virXMLFormatElement(buf, "driver", &driverBuf, NULL);
+    virXMLFormatElement(buf, "driver", &driverBuf, &driverChildBuf);
 }


diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d56a5a22e0..20cb058473 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -763,6 +763,7 @@ struct _virDomainControllerDef {
     unsigned int max_sectors;
     virTristateSwitch ioeventfd;
     unsigned int iothread; /* unused = 0, > 0 specific thread # */
+    GSList *iothreads; /* List of virDomainIothreadMappingDef */
     union {
         virDomainVirtioSerialOpts vioserial;
         virDomainPCIControllerOpts pciopts;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index ad3d17f0fd..f95316918d 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1260,7 +1260,7 @@ virDomainControllerDefValidate(const virDomainControllerDef *controller)
         }
     }

-    if (controller->iothread != 0) {
+    if (controller->iothread != 0 || controller->iothreads) {
         if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI ||
             !(controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI ||
               controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL ||
@@ -1269,6 +1269,14 @@ virDomainControllerDefValidate(const virDomainControllerDef *controller)
                            _("iothreads are supported only by 'virtio-scsi' controllers"));
             return -1;
         }
+
+        /* configuring both <driver iothread='n'> and it's <iothreads> sub-element
+         * isn't supported */
+        if (controller->iothread && controller->iothreads) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("controller driver 'iothread' attribute can't be used together with 'iothreads' subelement"));
+            return -1;
+        }
     }

     return 0;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 824da9d066..7dea0f1b0c 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -2605,7 +2605,11 @@
           <zeroOrMore>
             <element name="queue">
               <attribute name="id">
-                <ref name="unsignedInt"/>
+                <choice>
+                  <value>ctrl</value>
+                  <value>event</value>
+                  <ref name="unsignedInt"/>
+                </choice>
               </attribute>
             </element>
           </zeroOrMore>
@@ -3059,6 +3063,9 @@
             <optional>
               <ref name="driverIOThread"/>
             </optional>
+            <optional>
+              <ref name="iothreadMapping"/>
+            </optional>
             <ref name="virtioOptions"/>
           </element>
         </optional>
diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index b7499a376f..29ba358477 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -585,7 +585,8 @@ virDomainDriverDelIOThreadCheck(virDomainDef *def,
     }

     for (i = 0; i < def->ncontrollers; i++) {
-        if (def->controllers[i]->iothread == iothread_id) {
+        if (virDomainIothreadMappingDefHasIothread(def->controllers[i]->iothreads, iothread_id) ||
+            def->controllers[i]->iothread == iothread_id) {
             virReportError(VIR_ERR_INVALID_ARG,
                            _("cannot remove IOThread '%1$u' since it is being used by controller"),
                            iothread_id);
-- 
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