conf: Introduce dynamicMemslots attribute for virtio-mem

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>
This commit is contained in:
Michal Privoznik 2024-01-04 10:03:36 +01:00
parent 3d8445c25d
commit 5325820585
5 changed files with 37 additions and 2 deletions

View 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``

View 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

View 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;

View File

@ -7268,6 +7268,11 @@
<define name="memorydev-target">
<element name="target">
<optional>
<attribute name="dynamicMemslots">
<ref name="virYesNo"/>
</attribute>
</optional>
<interleave>
<element name="size">
<ref name="scaledInteger"/>

View 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>