diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 072f9a0fdcb58840142de2a9a14039dd41d61300..80172c18d0c25ee94fe4c46bb7943f8d1f32c6c6 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
diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng
index c45b6dfb28adf7ffe82ac4c429dadf423609e53a..1f1e0e36d59bf60ebd0a349f720a9001ded8fd17 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 8c446ca41856901e22722c19500c0a65360821d4..13af5b74a4988ecd4076e5235e5c6dcdbaef9f53 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 6786d81c9b0a6014d5496661c68b3958af641417..86229db654f98da12ae2d3e857c64deb850e22da 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 15d228ba9e62780bd6192cb01c25f14c7cf8665d..07d04fb2f986db29b908dbea8c61319dbd9a67d5 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 9307dd93d3d47ceab9bbdc530a131b81e1548100..97a3ca485d178cad3e5bfe9d469673737b422de0 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 7947fdb21923bc2c80b42fb27afc46b73cf1551b..85269be5651284216b39062ecdf38acf9cbf517a 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 5fea1bca41d9a58eb8002664be1c26995ddcd143..d28a751ebd1ae836e4303bf17533f19d7c83d5a1 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 f9270782d4fe12d564363dd422ef27d115b79097..cba83e754c295939d167da9596d898e366ca2b17 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 3d3b3f3cc3fcb0e3a138f8291edfe3de6dbc937a..147acc4c95a627742b985b9f08fed42198742232 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 d75cf5afa343c75eab85417efc43aa735d72b1ab..28c72f85a72d644bb196623b4644aa984fdafe1d 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 498610a217fed837e62f6fa2d455a7e048a2ca1d..292454588e556536429f23bdfdc57b6bfda4b053 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 be21c3eddd9332f09b40da7f20fa706a61cf712d..90e6efa5eaca5e48f6d1f2b558d49e2142d84a92 100644
--- a/tests/qemuxml2xmloutdata/hugepages-pages3.xml
+++ b/tests/qemuxml2xmloutdata/hugepages-pages3.xml
@@ -15,8 +15,8 @@
- |
- |
+ |
+ |