]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: Introduce dynamicMemslots attribute for virtio-mem
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 4 Jan 2024 09:03:36 +0000 (10:03 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 30 Jan 2024 09:44:36 +0000 (10:44 +0100)
Introduced in v8.2.0-rc0~74^2~2, QEMU now allows setting
.dynamic-memslots attribute for virtio-mem-pci devices. When
turned on, it allows memory exposed to guest to be split into
multiple memslots and thus smaller memory footprint (see the
original commit for detailed explanation).

Therefore, introduce new <target/> attribute which will control
that QEMU knob.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/schemas/domaincommon.rng
tests/qemuxmlconfdata/memory-hotplug-virtio-mem.xml

index 67d5f958d5567b22bdddabcc06108ab9e5e4102c..0a4f9d90007548f28623914468e930e0374e3f76 100644 (file)
@@ -8443,6 +8443,19 @@ Example: usage of the memory devices
    The ``node`` subelement configures the guest NUMA node to attach the memory
    to. The element shall be used only if the guest has NUMA nodes configured.
 
+   For ``virtio-mem`` optional attribute ``dynamicMemslots`` can be specified
+   (accepted values "yes"/"no") which allows hypervisor to spread memory into
+   multiple memory slots (allocate them dynamically based on the amount of
+   memory exposed to the guest), resulting in smaller memory footprint. But be
+   aware this may affect vhost-user devices. When enabled, older vhost-user
+   device implementations (such as virtiofs) may refuse to initialize resulting
+   in failed domain startup or device hotplug. When only modern vhost-user
+   based devices will be used or when no vhost-user devices are expected to be
+   used it's beneficial to enable this feature. The current default is
+   hypervisor dependant (for QEMU is "no"). If the default changes and you are
+   having difficulties with vhost-user devices, try toggling this to "no".
+   :since:`Since 10.1.0 and QEMU 8.2.0`
+
    The following optional elements may be used:
 
    ``label``
index 59d51c4c52399c34f7d36354d9ba40037be705be..fb5a5cc35198e42f53500d134444ff29d35efc6e 100644 (file)
@@ -13558,6 +13558,10 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
                                  &def->target.virtio_mem.requestedsize, false, false) < 0)
             return -1;
 
+        if (virXMLPropTristateBool(node, "dynamicMemslots", VIR_XML_PROP_NONE,
+                                   &def->target.virtio_mem.dynamicMemslots) < 0)
+            return -1;
+
         addrNode = virXPathNode("./address", ctxt);
         addr = &def->target.virtio_mem.address;
         break;
@@ -21232,6 +21236,12 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDef *src,
                            src->target.virtio_mem.address);
             return false;
         }
+
+        if (src->target.virtio_mem.dynamicMemslots != dst->target.virtio_mem.dynamicMemslots) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Target memory device 'dynamicMemslots' property doesn't match source memory device"));
+            return false;
+        }
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
@@ -25448,6 +25458,7 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
                                unsigned int flags)
 {
     g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
 
     virBufferAsprintf(&childBuf, "<size unit='KiB'>%llu</size>\n", def->size);
     if (def->targetNode >= 0)
@@ -25487,6 +25498,11 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
         if (def->target.virtio_mem.address)
             virBufferAsprintf(&childBuf, "<address base='0x%llx'/>\n",
                               def->target.virtio_mem.address);
+
+        if (def->target.virtio_mem.dynamicMemslots) {
+            virBufferAsprintf(&attrBuf, " dynamicMemslots='%s'",
+                              virTristateBoolTypeToString(def->target.virtio_mem.dynamicMemslots));
+        }
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
@@ -25496,7 +25512,7 @@ virDomainMemoryTargetDefFormat(virBuffer *buf,
         break;
     }
 
-    virXMLFormatElement(buf, "target", NULL, &childBuf);
+    virXMLFormatElement(buf, "target", &attrBuf, &childBuf);
 }
 
 static int
index d176bda5f8db9477b64b2f375cd45c4e10b5047f..bd283d42df69aa32a006eb99530f05fd3519f438 100644 (file)
@@ -2676,6 +2676,7 @@ struct _virDomainMemoryDef {
             unsigned long long currentsize; /* kibibytes, valid for an active
                                                domain only and parsed */
             unsigned long long address; /* address where memory is mapped */
+            virTristateBool dynamicMemslots;
         } virtio_mem;
         struct {
         } sgx_epc;
index a34427c33027c4fefc8b0f452b004b65dda9c8a9..df44cd9857cd937170b8dc6dae47684a91241074 100644 (file)
 
   <define name="memorydev-target">
     <element name="target">
+      <optional>
+        <attribute name="dynamicMemslots">
+          <ref name="virYesNo"/>
+        </attribute>
+      </optional>
       <interleave>
         <element name="size">
           <ref name="scaledInteger"/>
index 52fa6b14e9173edb1c14b36e6d392a8a05533cd4..20282a131b69292c706b7c6aedbd5b6f3d273c89 100644 (file)
@@ -60,7 +60,7 @@
         <nodemask>1-3</nodemask>
         <pagesize unit='KiB'>2048</pagesize>
       </source>
-      <target>
+      <target dynamicMemslots='yes'>
         <size unit='KiB'>2097152</size>
         <node>0</node>
         <block unit='KiB'>2048</block>