render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
49d448
From 19f7e6dc950baf346738f462ac5c6b815c04edcc Mon Sep 17 00:00:00 2001
49d448
Message-Id: <19f7e6dc950baf346738f462ac5c6b815c04edcc@dist-git>
49d448
From: Michal Privoznik <mprivozn@redhat.com>
49d448
Date: Mon, 21 Mar 2022 16:49:25 +0100
49d448
Subject: [PATCH] conf: Introduce memory allocation threads
49d448
49d448
Since its v5.0.0 release QEMU is capable of specifying number of
49d448
threads used to allocate memory. It defaults to 1, which may be
49d448
too low for humongous guests with gigantic pages.
49d448
49d448
In general, on QEMU cmd line level it is possible to use
49d448
different number of threads per each memory-backend-* object, in
49d448
practical terms it's not useful. Therefore, use <memoryBacking/>
49d448
to set guest wide value and let all memory devices 'inherit' it,
49d448
silently. IOW, don't introduce per device knob because that would
49d448
only complicate things for a little or no benefit.
49d448
49d448
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
49d448
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
49d448
(cherry picked from commit ba7f98126fa84d354ce72929b77cc111a9a557a9)
49d448
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2067126
49d448
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
49d448
---
49d448
 docs/formatdomain.rst                        |  8 +++++---
49d448
 docs/schemas/domaincommon.rng                | 19 +++++++++++++------
49d448
 src/conf/domain_conf.c                       | 15 ++++++++++++++-
49d448
 src/conf/domain_conf.h                       |  1 +
49d448
 tests/qemuxml2argvdata/memfd-memory-numa.xml |  2 +-
49d448
 5 files changed, 34 insertions(+), 11 deletions(-)
49d448
49d448
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
49d448
index 8128e43da4..17e89a0c0d 100644
49d448
--- a/docs/formatdomain.rst
49d448
+++ b/docs/formatdomain.rst
49d448
@@ -977,7 +977,7 @@ Memory Backing
49d448
        <locked/>
49d448
        <source type="file|anonymous|memfd"/>
49d448
        <access mode="shared|private"/>
49d448
-       <allocation mode="immediate|ondemand"/>
49d448
+       <allocation mode="immediate|ondemand" threads='8'/>
49d448
        <discard/>
49d448
      </memoryBacking>
49d448
      ...
49d448
@@ -1026,8 +1026,10 @@ influence how virtual memory pages are backed by host pages.
49d448
    Using the ``mode`` attribute, specify if the memory is to be "shared" or
49d448
    "private". This can be overridden per numa node by ``memAccess``.
49d448
 ``allocation``
49d448
-   Using the ``mode`` attribute, specify when to allocate the memory by
49d448
-   supplying either "immediate" or "ondemand".
49d448
+   Using the optional ``mode`` attribute, specify when to allocate the memory by
49d448
+   supplying either "immediate" or "ondemand". :since:`Since 8.2.0` it is
49d448
+   possible to set the number of threads that hypervisor uses to allocate
49d448
+   memory via ``threads`` attribute.
49d448
 ``discard``
49d448
    When set and supported by hypervisor the memory content is discarded just
49d448
    before guest shuts down (or when DIMM module is unplugged). Please note that
49d448
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
49d448
index 7fa5c2b8b5..c9c1529979 100644
49d448
--- a/docs/schemas/domaincommon.rng
49d448
+++ b/docs/schemas/domaincommon.rng
49d448
@@ -745,12 +745,19 @@
49d448
             </optional>
49d448
             <optional>
49d448
               <element name="allocation">
49d448
-                <attribute name="mode">
49d448
-                  <choice>
49d448
-                    <value>immediate</value>
49d448
-                    <value>ondemand</value>
49d448
-                  </choice>
49d448
-                </attribute>
49d448
+                <optional>
49d448
+                  <attribute name="mode">
49d448
+                    <choice>
49d448
+                      <value>immediate</value>
49d448
+                      <value>ondemand</value>
49d448
+                    </choice>
49d448
+                  </attribute>
49d448
+                </optional>
49d448
+                <optional>
49d448
+                  <attribute name="threads">
49d448
+                    <ref name="unsignedInt"/>
49d448
+                  </attribute>
49d448
+                </optional>
49d448
               </element>
49d448
             </optional>
49d448
             <optional>
49d448
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
49d448
index 5691b8d2d5..805a15848e 100644
49d448
--- a/src/conf/domain_conf.c
49d448
+++ b/src/conf/domain_conf.c
49d448
@@ -19095,6 +19095,13 @@ virDomainDefParseMemory(virDomainDef *def,
49d448
         VIR_FREE(tmp);
49d448
     }
49d448
 
49d448
+    if (virXPathUInt("string(./memoryBacking/allocation/@threads)",
49d448
+                     ctxt, &def->mem.allocation_threads) == -2) {
49d448
+        virReportError(VIR_ERR_XML_ERROR, "%s",
49d448
+                       _("Failed to parse memory allocation threads"));
49d448
+        return -1;
49d448
+    }
49d448
+
49d448
     if (virXPathNode("./memoryBacking/hugepages", ctxt)) {
49d448
         /* hugepages will be used */
49d448
         if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) {
49d448
@@ -27639,6 +27646,7 @@ virDomainMemorybackingFormat(virBuffer *buf,
49d448
                              const virDomainMemtune *mem)
49d448
 {
49d448
     g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
49d448
+    g_auto(virBuffer) allocAttrBuf = VIR_BUFFER_INITIALIZER;
49d448
 
49d448
     if (mem->nhugepages)
49d448
         virDomainHugepagesFormat(&childBuf, mem->hugepages, mem->nhugepages);
49d448
@@ -27653,8 +27661,13 @@ virDomainMemorybackingFormat(virBuffer *buf,
49d448
         virBufferAsprintf(&childBuf, "<access mode='%s'/>\n",
49d448
                           virDomainMemoryAccessTypeToString(mem->access));
49d448
     if (mem->allocation)
49d448
-        virBufferAsprintf(&childBuf, "<allocation mode='%s'/>\n",
49d448
+        virBufferAsprintf(&allocAttrBuf, " mode='%s'",
49d448
                           virDomainMemoryAllocationTypeToString(mem->allocation));
49d448
+    if (mem->allocation_threads > 0)
49d448
+        virBufferAsprintf(&allocAttrBuf, " threads='%u'", mem->allocation_threads);
49d448
+
49d448
+    virXMLFormatElement(&childBuf, "allocation", &allocAttrBuf, NULL);
49d448
+
49d448
     if (mem->discard)
49d448
         virBufferAddLit(&childBuf, "<discard/>\n");
49d448
 
49d448
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
49d448
index 144ba4dd12..10af94e2e4 100644
49d448
--- a/src/conf/domain_conf.h
49d448
+++ b/src/conf/domain_conf.h
49d448
@@ -2677,6 +2677,7 @@ struct _virDomainMemtune {
49d448
     int source; /* enum virDomainMemorySource */
49d448
     int access; /* enum virDomainMemoryAccess */
49d448
     int allocation; /* enum virDomainMemoryAllocation */
49d448
+    unsigned int allocation_threads;
49d448
 
49d448
     virTristateBool discard;
49d448
 };
49d448
diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.xml b/tests/qemuxml2argvdata/memfd-memory-numa.xml
49d448
index 1ebcee8939..1ac87e3aef 100644
49d448
--- a/tests/qemuxml2argvdata/memfd-memory-numa.xml
49d448
+++ b/tests/qemuxml2argvdata/memfd-memory-numa.xml
49d448
@@ -10,7 +10,7 @@
49d448
     </hugepages>
49d448
     <source type='memfd'/>
49d448
     <access mode='shared'/>
49d448
-    <allocation mode='immediate'/>
49d448
+    <allocation mode='immediate' threads='8'/>
49d448
   </memoryBacking>
49d448
   <vcpu placement='static'>8</vcpu>
49d448
   <numatune>
49d448
-- 
49d448
2.35.1
49d448