conf: Introduce memory allocation threads

Since its v5.0.0 release QEMU is capable of specifying number of
threads used to allocate memory. It defaults to 1, which may be
too low for humongous guests with gigantic pages.

In general, on QEMU cmd line level it is possible to use
different number of threads per each memory-backend-* object, in
practical terms it's not useful. Therefore, use <memoryBacking/>
to set guest wide value and let all memory devices 'inherit' it,
silently. IOW, don't introduce per device knob because that would
only complicate things for a little or no benefit.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Michal Privoznik 2022-03-21 16:49:25 +01:00
parent 42d7c3c4da
commit ba7f98126f
5 changed files with 34 additions and 11 deletions

View File

@ -1004,7 +1004,7 @@ Memory Backing
<locked/>
<source type="file|anonymous|memfd"/>
<access mode="shared|private"/>
<allocation mode="immediate|ondemand"/>
<allocation mode="immediate|ondemand" threads='8'/>
<discard/>
</memoryBacking>
...
@ -1053,8 +1053,10 @@ influence how virtual memory pages are backed by host pages.
Using the ``mode`` attribute, specify if the memory is to be "shared" or
"private". This can be overridden per numa node by ``memAccess``.
``allocation``
Using the ``mode`` attribute, specify when to allocate the memory by
supplying either "immediate" or "ondemand".
Using the optional ``mode`` attribute, specify when to allocate the memory by
supplying either "immediate" or "ondemand". :since:`Since 8.2.0` it is
possible to set the number of threads that hypervisor uses to allocate
memory via ``threads`` attribute.
``discard``
When set and supported by hypervisor the memory content is discarded just
before guest shuts down (or when DIMM module is unplugged). Please note that

View File

@ -18915,6 +18915,13 @@ virDomainDefParseMemory(virDomainDef *def,
VIR_FREE(tmp);
}
if (virXPathUInt("string(./memoryBacking/allocation/@threads)",
ctxt, &def->mem.allocation_threads) == -2) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Failed to parse memory allocation threads"));
return -1;
}
if (virXPathNode("./memoryBacking/hugepages", ctxt)) {
/* hugepages will be used */
if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) {
@ -27465,6 +27472,7 @@ virDomainMemorybackingFormat(virBuffer *buf,
const virDomainMemtune *mem)
{
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
g_auto(virBuffer) allocAttrBuf = VIR_BUFFER_INITIALIZER;
if (mem->nhugepages)
virDomainHugepagesFormat(&childBuf, mem->hugepages, mem->nhugepages);
@ -27479,8 +27487,13 @@ virDomainMemorybackingFormat(virBuffer *buf,
virBufferAsprintf(&childBuf, "<access mode='%s'/>\n",
virDomainMemoryAccessTypeToString(mem->access));
if (mem->allocation)
virBufferAsprintf(&childBuf, "<allocation mode='%s'/>\n",
virBufferAsprintf(&allocAttrBuf, " mode='%s'",
virDomainMemoryAllocationTypeToString(mem->allocation));
if (mem->allocation_threads > 0)
virBufferAsprintf(&allocAttrBuf, " threads='%u'", mem->allocation_threads);
virXMLFormatElement(&childBuf, "allocation", &allocAttrBuf, NULL);
if (mem->discard)
virBufferAddLit(&childBuf, "<discard/>\n");

View File

@ -2702,6 +2702,7 @@ struct _virDomainMemtune {
int source; /* enum virDomainMemorySource */
int access; /* enum virDomainMemoryAccess */
int allocation; /* enum virDomainMemoryAllocation */
unsigned int allocation_threads;
virTristateBool discard;
};

View File

@ -740,12 +740,19 @@
</optional>
<optional>
<element name="allocation">
<attribute name="mode">
<choice>
<value>immediate</value>
<value>ondemand</value>
</choice>
</attribute>
<optional>
<attribute name="mode">
<choice>
<value>immediate</value>
<value>ondemand</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="threads">
<ref name="unsignedInt"/>
</attribute>
</optional>
</element>
</optional>
<optional>

View File

@ -10,7 +10,7 @@
</hugepages>
<source type='memfd'/>
<access mode='shared'/>
<allocation mode='immediate'/>
<allocation mode='immediate' threads='8'/>
</memoryBacking>
<vcpu placement='static'>8</vcpu>
<numatune>