From e60a964e51cb0aecb060f1a1cc2884586e00ddeb Mon Sep 17 00:00:00 2001 Message-Id: From: Michal Privoznik Date: Mon, 21 Mar 2022 16:49:25 +0100 Subject: [PATCH] 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 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 Reviewed-by: Martin Kletzander (cherry picked from commit ba7f98126fa84d354ce72929b77cc111a9a557a9) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2075569 Signed-off-by: Michal Privoznik --- docs/formatdomain.rst | 8 +++++--- docs/schemas/domaincommon.rng | 19 +++++++++++++------ src/conf/domain_conf.c | 15 ++++++++++++++- src/conf/domain_conf.h | 1 + tests/qemuxml2argvdata/memfd-memory-numa.xml | 2 +- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 8128e43da4..17e89a0c0d 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -977,7 +977,7 @@ Memory Backing - + ... @@ -1026,8 +1026,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 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 7fa5c2b8b5..c9c1529979 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -745,12 +745,19 @@ - - - immediate - ondemand - - + + + + immediate + ondemand + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5691b8d2d5..805a15848e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19095,6 +19095,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) { @@ -27639,6 +27646,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); @@ -27653,8 +27661,13 @@ virDomainMemorybackingFormat(virBuffer *buf, virBufferAsprintf(&childBuf, "\n", virDomainMemoryAccessTypeToString(mem->access)); if (mem->allocation) - virBufferAsprintf(&childBuf, "\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, "\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 144ba4dd12..10af94e2e4 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2677,6 +2677,7 @@ struct _virDomainMemtune { int source; /* enum virDomainMemorySource */ int access; /* enum virDomainMemoryAccess */ int allocation; /* enum virDomainMemoryAllocation */ + unsigned int allocation_threads; virTristateBool discard; }; diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.xml b/tests/qemuxml2argvdata/memfd-memory-numa.xml index 1ebcee8939..1ac87e3aef 100644 --- a/tests/qemuxml2argvdata/memfd-memory-numa.xml +++ b/tests/qemuxml2argvdata/memfd-memory-numa.xml @@ -10,7 +10,7 @@ - + 8 -- 2.35.1