From 2300c92fe0d596258ed2f7da1b867d0ce2112f90 Mon Sep 17 00:00:00 2001
From: Michal Privoznik
Date: Fri, 11 May 2018 15:08:53 +0200
Subject: [PATCH] conf: Introduce memoryBacking/discard
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QEMU has possibility to call madvise(.., MADV_REMOVE) in some
cases. Expose this feature to users by new element/attribute
discard.
Signed-off-by: Michal Privoznik
Reviewed-by: Ján Tomko
---
docs/formatdomain.html.in | 34 ++++++++++++++++--
docs/schemas/cputypes.rng | 5 +++
docs/schemas/domaincommon.rng | 10 ++++++
src/conf/domain_conf.c | 36 ++++++++++++++++++-
src/conf/domain_conf.h | 3 ++
src/conf/numa_conf.c | 27 ++++++++++++++
src/conf/numa_conf.h | 3 ++
src/libvirt_private.syms | 1 +
tests/qemuxml2argvdata/hugepages-pages.xml | 3 +-
tests/qemuxml2argvdata/hugepages-pages3.xml | 4 +--
tests/qemuxml2argvdata/hugepages-pages7.xml | 4 +--
tests/qemuxml2xmloutdata/hugepages-pages.xml | 3 +-
tests/qemuxml2xmloutdata/hugepages-pages3.xml | 4 +--
13 files changed, 126 insertions(+), 11 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 072f9a0fdc..80172c18d0 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1016,6 +1016,7 @@
<source type="file|anonymous"/>
<access mode="shared|private"/>
<allocation mode="immediate|ondemand"/>
+ <discard/>
</memoryBacking>
...
</domain>
@@ -1070,6 +1071,14 @@
numa node by memAccess
allocation
Specify when allocate the memory
+ 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 this is
+ just an optimization and is not guaranteed to work in
+ all cases (e.g. when hypervisor crashes).
+ Since 4.4.0 (QEMU/KVM only)
+
@@ -1608,7 +1617,7 @@
<cpu>
...
<numa>
- <cell id='0' cpus='0-3' memory='512000' unit='KiB'/>
+ <cell id='0' cpus='0-3' memory='512000' unit='KiB' discard='yes'/>
<cell id='1' cpus='4-7' memory='512000' unit='KiB' memAccess='shared'/>
</numa>
...
@@ -1634,6 +1643,13 @@
memAccess
can control whether the memory is to be
mapped as "shared" or "private". This is valid only for
hugepages-backed memory and nvdimm modules.
+
+ Each cell
element can have an optional
+ discard
attribute which fine tunes the discard
+ feature for given numa node as described under
+ Memory Backing .
+ Accepted values are yes
and no
.
+ Since 4.4.0
diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng
index c45b6dfb28..1f1e0e36d5 100644
--- a/docs/schemas/cputypes.rng
+++ b/docs/schemas/cputypes.rng
@@ -129,6 +129,11 @@
+
+
+
+
+
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8c446ca418..13af5b74a4 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -633,6 +633,11 @@
+
+
+
+
+
@@ -5124,6 +5129,11 @@
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6786d81c9b..86229db654 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5516,6 +5516,20 @@ virDomainVideoDefValidate(const virDomainVideoDef *video)
}
+static int
+virDomainMemoryDefValidate(const virDomainMemoryDef *mem)
+{
+ if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
+ mem->discard == VIR_TRISTATE_BOOL_YES) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("discard is not supported for nvdimms"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
const virDomainDef *def)
@@ -5548,6 +5562,9 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_VIDEO:
return virDomainVideoDefValidate(dev->data.video);
+ case VIR_DOMAIN_DEVICE_MEMORY:
+ return virDomainMemoryDefValidate(dev->data.memory);
+
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_INPUT:
@@ -5560,7 +5577,6 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
- case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU:
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LAST:
@@ -15673,6 +15689,16 @@ virDomainMemoryDefParseXML(virDomainXMLOptionPtr xmlopt,
}
VIR_FREE(tmp);
+ if ((tmp = virXMLPropString(memdevNode, "discard"))) {
+ if ((val = virTristateBoolTypeFromString(tmp)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid discard value '%s'"), tmp);
+ goto error;
+ }
+
+ def->discard = val;
+ }
+
/* source */
if ((node = virXPathNode("./source", ctxt)) &&
virDomainMemorySourceDefParseXML(node, ctxt, def) < 0)
@@ -18999,6 +19025,9 @@ virDomainDefParseXML(xmlDocPtr xml,
if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt))
def->mem.locked = true;
+ if (virXPathBoolean("boolean(./memoryBacking/discard)", ctxt))
+ def->mem.discard = VIR_TRISTATE_BOOL_YES;
+
/* Extract blkio cgroup tunables */
if (virXPathUInt("string(./blkiotune/weight)", ctxt,
&def->blkio.weight) < 0)
@@ -25259,6 +25288,9 @@ virDomainMemoryDefFormat(virBufferPtr buf,
if (def->access)
virBufferAsprintf(buf, " access='%s'",
virDomainMemoryAccessTypeToString(def->access));
+ if (def->discard)
+ virBufferAsprintf(buf, " discard='%s'",
+ virTristateBoolTypeToString(def->discard));
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
@@ -26605,6 +26637,8 @@ virDomainMemtuneFormat(virBufferPtr buf,
if (mem->allocation)
virBufferAsprintf(&childBuf, " \n",
virDomainMemoryAllocationTypeToString(mem->allocation));
+ if (mem->discard)
+ virBufferAddLit(&childBuf, " \n");
if (virXMLFormatElement(buf, "memoryBacking", NULL, &childBuf) < 0)
goto cleanup;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 15d228ba9e..07d04fb2f9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2105,6 +2105,7 @@ typedef enum {
struct _virDomainMemoryDef {
virDomainMemoryAccess access;
+ virTristateBool discard;
/* source */
virBitmapPtr sourceNodes;
@@ -2267,6 +2268,8 @@ struct _virDomainMemtune {
int source; /* enum virDomainMemorySource */
int access; /* enum virDomainMemoryAccess */
int allocation; /* enum virDomainMemoryAllocation */
+
+ virTristateBool discard;
};
typedef struct _virDomainPowerManagement virDomainPowerManagement;
diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
index 9307dd93d3..97a3ca485d 100644
--- a/src/conf/numa_conf.c
+++ b/src/conf/numa_conf.c
@@ -77,6 +77,7 @@ struct _virDomainNuma {
virBitmapPtr nodeset; /* host memory nodes where this guest node resides */
virDomainNumatuneMemMode mode; /* memory mode selection */
virDomainMemoryAccess memAccess; /* shared memory access configuration */
+ virTristateBool discard; /* discard-data for memory-backend-file */
struct _virDomainNumaDistance {
unsigned int value; /* locality value for node i->j or j->i */
@@ -947,6 +948,18 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
VIR_FREE(tmp);
}
+ if ((tmp = virXMLPropString(nodes[i], "discard"))) {
+ if ((rc = virTristateBoolTypeFromString(tmp)) <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Invalid 'discard' attribute value '%s'"),
+ tmp);
+ goto cleanup;
+ }
+
+ def->mem_nodes[cur_cell].discard = rc;
+ VIR_FREE(tmp);
+ }
+
/* Parse NUMA distances info */
if (virDomainNumaDefNodeDistanceParseXML(def, ctxt, cur_cell) < 0)
goto cleanup;
@@ -967,6 +980,7 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf,
virDomainNumaPtr def)
{
virDomainMemoryAccess memAccess;
+ virTristateBool discard;
char *cpustr;
size_t ncells = virDomainNumaGetNodeCount(def);
size_t i;
@@ -980,6 +994,7 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf,
int ndistances;
memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i);
+ discard = virDomainNumaGetNodeDiscard(def, i);
if (!(cpustr = virBitmapFormat(virDomainNumaGetNodeCpumask(def, i))))
return -1;
@@ -994,6 +1009,10 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf,
virBufferAsprintf(buf, " memAccess='%s'",
virDomainMemoryAccessTypeToString(memAccess));
+ if (discard)
+ virBufferAsprintf(buf, " discard='%s'",
+ virTristateBoolTypeToString(discard));
+
ndistances = def->mem_nodes[i].ndistances;
if (ndistances == 0) {
virBufferAddLit(buf, "/>\n");
@@ -1304,6 +1323,14 @@ virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa,
}
+virTristateBool
+virDomainNumaGetNodeDiscard(virDomainNumaPtr numa,
+ size_t node)
+{
+ return numa->mem_nodes[node].discard;
+}
+
+
unsigned long long
virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
size_t node)
diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
index 7947fdb219..85269be565 100644
--- a/src/conf/numa_conf.h
+++ b/src/conf/numa_conf.h
@@ -102,6 +102,9 @@ virBitmapPtr virDomainNumaGetNodeCpumask(virDomainNumaPtr numa,
virDomainMemoryAccess virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa,
size_t node)
ATTRIBUTE_NONNULL(1);
+virTristateBool virDomainNumaGetNodeDiscard(virDomainNumaPtr numa,
+ size_t node)
+ ATTRIBUTE_NONNULL(1);
unsigned long long virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
size_t node)
ATTRIBUTE_NONNULL(1);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5fea1bca41..d28a751ebd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -750,6 +750,7 @@ virDomainNumaGetMaxCPUID;
virDomainNumaGetMemorySize;
virDomainNumaGetNodeCount;
virDomainNumaGetNodeCpumask;
+virDomainNumaGetNodeDiscard;
virDomainNumaGetNodeDistance;
virDomainNumaGetNodeMemoryAccessMode;
virDomainNumaGetNodeMemorySize;
diff --git a/tests/qemuxml2argvdata/hugepages-pages.xml b/tests/qemuxml2argvdata/hugepages-pages.xml
index f9270782d4..cba83e754c 100644
--- a/tests/qemuxml2argvdata/hugepages-pages.xml
+++ b/tests/qemuxml2argvdata/hugepages-pages.xml
@@ -8,6 +8,7 @@
+
4
@@ -21,7 +22,7 @@
|
- |
+ |
|
|
diff --git a/tests/qemuxml2argvdata/hugepages-pages3.xml b/tests/qemuxml2argvdata/hugepages-pages3.xml
index 3d3b3f3cc3..147acc4c95 100644
--- a/tests/qemuxml2argvdata/hugepages-pages3.xml
+++ b/tests/qemuxml2argvdata/hugepages-pages3.xml
@@ -15,8 +15,8 @@
- |
- |
+ |
+ |
diff --git a/tests/qemuxml2argvdata/hugepages-pages7.xml b/tests/qemuxml2argvdata/hugepages-pages7.xml
index d75cf5afa3..28c72f85a7 100644
--- a/tests/qemuxml2argvdata/hugepages-pages7.xml
+++ b/tests/qemuxml2argvdata/hugepages-pages7.xml
@@ -43,7 +43,7 @@
-
+
1-3
1048576
@@ -54,7 +54,7 @@
-
+
524287
0
diff --git a/tests/qemuxml2xmloutdata/hugepages-pages.xml b/tests/qemuxml2xmloutdata/hugepages-pages.xml
index 498610a217..292454588e 100644
--- a/tests/qemuxml2xmloutdata/hugepages-pages.xml
+++ b/tests/qemuxml2xmloutdata/hugepages-pages.xml
@@ -8,6 +8,7 @@
+
4
@@ -21,7 +22,7 @@
|
- |
+ |
|
|
diff --git a/tests/qemuxml2xmloutdata/hugepages-pages3.xml b/tests/qemuxml2xmloutdata/hugepages-pages3.xml
index be21c3eddd..90e6efa5ea 100644
--- a/tests/qemuxml2xmloutdata/hugepages-pages3.xml
+++ b/tests/qemuxml2xmloutdata/hugepages-pages3.xml
@@ -15,8 +15,8 @@
- |
- |
+ |
+ |