提交 2300c92f 编写于 作者: M Michal Privoznik

conf: Introduce memoryBacking/discard

QEMU has possibility to call madvise(.., MADV_REMOVE) in some
cases. Expose this feature to users by new element/attribute
discard.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 03290757
...@@ -1016,6 +1016,7 @@ ...@@ -1016,6 +1016,7 @@
&lt;source type="file|anonymous"/&gt; &lt;source type="file|anonymous"/&gt;
&lt;access mode="shared|private"/&gt; &lt;access mode="shared|private"/&gt;
&lt;allocation mode="immediate|ondemand"/&gt; &lt;allocation mode="immediate|ondemand"/&gt;
&lt;discard/&gt;
&lt;/memoryBacking&gt; &lt;/memoryBacking&gt;
... ...
&lt;/domain&gt; &lt;/domain&gt;
...@@ -1070,6 +1071,14 @@ ...@@ -1070,6 +1071,14 @@
numa node by <code>memAccess</code></dd> numa node by <code>memAccess</code></dd>
<dt><code>allocation</code></dt> <dt><code>allocation</code></dt>
<dd>Specify when allocate the memory</dd> <dd>Specify when allocate the memory</dd>
<dt><code>discard</code></dt>
<dd>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).
<span class="since">Since 4.4.0</span> (QEMU/KVM only)
</dd>
</dl> </dl>
...@@ -1608,7 +1617,7 @@ ...@@ -1608,7 +1617,7 @@
&lt;cpu&gt; &lt;cpu&gt;
... ...
&lt;numa&gt; &lt;numa&gt;
&lt;cell id='0' cpus='0-3' memory='512000' unit='KiB'/&gt; &lt;cell id='0' cpus='0-3' memory='512000' unit='KiB' discard='yes'/&gt;
&lt;cell id='1' cpus='4-7' memory='512000' unit='KiB' memAccess='shared'/&gt; &lt;cell id='1' cpus='4-7' memory='512000' unit='KiB' memAccess='shared'/&gt;
&lt;/numa&gt; &lt;/numa&gt;
... ...
...@@ -1634,6 +1643,13 @@ ...@@ -1634,6 +1643,13 @@
<code>memAccess</code> can control whether the memory is to be <code>memAccess</code> can control whether the memory is to be
mapped as "shared" or "private". This is valid only for mapped as "shared" or "private". This is valid only for
hugepages-backed memory and nvdimm modules. hugepages-backed memory and nvdimm modules.
Each <code>cell</code> element can have an optional
<code>discard</code> attribute which fine tunes the discard
feature for given numa node as described under
<a href="#elementsMemoryBacking">Memory Backing</a>.
Accepted values are <code>yes</code> and <code>no</code>.
<span class='since'>Since 4.4.0</span>
</p> </p>
<p> <p>
...@@ -7883,7 +7899,7 @@ qemu-kvm -net nic,model=? /dev/null ...@@ -7883,7 +7899,7 @@ qemu-kvm -net nic,model=? /dev/null
<pre> <pre>
... ...
&lt;devices&gt; &lt;devices&gt;
&lt;memory model='dimm' access='private'&gt; &lt;memory model='dimm' access='private' discard='yes'&gt;
&lt;target&gt; &lt;target&gt;
&lt;size unit='KiB'&gt;524287&lt;/size&gt; &lt;size unit='KiB'&gt;524287&lt;/size&gt;
&lt;node&gt;0&lt;/node&gt; &lt;node&gt;0&lt;/node&gt;
...@@ -7937,6 +7953,20 @@ qemu-kvm -net nic,model=? /dev/null ...@@ -7937,6 +7953,20 @@ qemu-kvm -net nic,model=? /dev/null
</p> </p>
</dd> </dd>
<dt><code>discard</code></dt>
<dd>
<p>
An optional attribute <code>discard</code>
(<span class="since">since 4.4.0</span>) that provides
capability to fine tune discard of data on per module
basis. Accepted values are <code>yes</code> and
<code>no</code>. The feature is described here:
<a href="#elementsMemoryBacking">Memory Backing</a>.
This attribute is allowed only for
<code>model='dimm'</code>.
</p>
</dd>
<dt><code>source</code></dt> <dt><code>source</code></dt>
<dd> <dd>
<p> <p>
......
...@@ -129,6 +129,11 @@ ...@@ -129,6 +129,11 @@
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
<optional>
<attribute name="discard">
<ref name="virYesNo"/>
</attribute>
</optional>
<optional> <optional>
<element name="distances"> <element name="distances">
<oneOrMore> <oneOrMore>
......
...@@ -633,6 +633,11 @@ ...@@ -633,6 +633,11 @@
</attribute> </attribute>
</element> </element>
</optional> </optional>
<optional>
<element name="discard">
<empty/>
</element>
</optional>
</interleave> </interleave>
</element> </element>
</optional> </optional>
...@@ -5124,6 +5129,11 @@ ...@@ -5124,6 +5129,11 @@
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
<optional>
<attribute name="discard">
<ref name="virYesNo"/>
</attribute>
</optional>
<interleave> <interleave>
<optional> <optional>
<ref name="memorydev-source"/> <ref name="memorydev-source"/>
......
...@@ -5516,6 +5516,20 @@ virDomainVideoDefValidate(const virDomainVideoDef *video) ...@@ -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 static int
virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
const virDomainDef *def) const virDomainDef *def)
...@@ -5548,6 +5562,9 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, ...@@ -5548,6 +5562,9 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_VIDEO: case VIR_DOMAIN_DEVICE_VIDEO:
return virDomainVideoDefValidate(dev->data.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_LEASE:
case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_INPUT:
...@@ -5560,7 +5577,6 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, ...@@ -5560,7 +5577,6 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_MEMORY:
case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_IOMMU:
case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_LAST:
...@@ -15673,6 +15689,16 @@ virDomainMemoryDefParseXML(virDomainXMLOptionPtr xmlopt, ...@@ -15673,6 +15689,16 @@ virDomainMemoryDefParseXML(virDomainXMLOptionPtr xmlopt,
} }
VIR_FREE(tmp); 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 */ /* source */
if ((node = virXPathNode("./source", ctxt)) && if ((node = virXPathNode("./source", ctxt)) &&
virDomainMemorySourceDefParseXML(node, ctxt, def) < 0) virDomainMemorySourceDefParseXML(node, ctxt, def) < 0)
...@@ -18999,6 +19025,9 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -18999,6 +19025,9 @@ virDomainDefParseXML(xmlDocPtr xml,
if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt)) if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt))
def->mem.locked = true; def->mem.locked = true;
if (virXPathBoolean("boolean(./memoryBacking/discard)", ctxt))
def->mem.discard = VIR_TRISTATE_BOOL_YES;
/* Extract blkio cgroup tunables */ /* Extract blkio cgroup tunables */
if (virXPathUInt("string(./blkiotune/weight)", ctxt, if (virXPathUInt("string(./blkiotune/weight)", ctxt,
&def->blkio.weight) < 0) &def->blkio.weight) < 0)
...@@ -25259,6 +25288,9 @@ virDomainMemoryDefFormat(virBufferPtr buf, ...@@ -25259,6 +25288,9 @@ virDomainMemoryDefFormat(virBufferPtr buf,
if (def->access) if (def->access)
virBufferAsprintf(buf, " access='%s'", virBufferAsprintf(buf, " access='%s'",
virDomainMemoryAccessTypeToString(def->access)); virDomainMemoryAccessTypeToString(def->access));
if (def->discard)
virBufferAsprintf(buf, " discard='%s'",
virTristateBoolTypeToString(def->discard));
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
...@@ -26605,6 +26637,8 @@ virDomainMemtuneFormat(virBufferPtr buf, ...@@ -26605,6 +26637,8 @@ virDomainMemtuneFormat(virBufferPtr buf,
if (mem->allocation) if (mem->allocation)
virBufferAsprintf(&childBuf, "<allocation mode='%s'/>\n", virBufferAsprintf(&childBuf, "<allocation mode='%s'/>\n",
virDomainMemoryAllocationTypeToString(mem->allocation)); virDomainMemoryAllocationTypeToString(mem->allocation));
if (mem->discard)
virBufferAddLit(&childBuf, "<discard/>\n");
if (virXMLFormatElement(buf, "memoryBacking", NULL, &childBuf) < 0) if (virXMLFormatElement(buf, "memoryBacking", NULL, &childBuf) < 0)
goto cleanup; goto cleanup;
......
...@@ -2105,6 +2105,7 @@ typedef enum { ...@@ -2105,6 +2105,7 @@ typedef enum {
struct _virDomainMemoryDef { struct _virDomainMemoryDef {
virDomainMemoryAccess access; virDomainMemoryAccess access;
virTristateBool discard;
/* source */ /* source */
virBitmapPtr sourceNodes; virBitmapPtr sourceNodes;
...@@ -2267,6 +2268,8 @@ struct _virDomainMemtune { ...@@ -2267,6 +2268,8 @@ struct _virDomainMemtune {
int source; /* enum virDomainMemorySource */ int source; /* enum virDomainMemorySource */
int access; /* enum virDomainMemoryAccess */ int access; /* enum virDomainMemoryAccess */
int allocation; /* enum virDomainMemoryAllocation */ int allocation; /* enum virDomainMemoryAllocation */
virTristateBool discard;
}; };
typedef struct _virDomainPowerManagement virDomainPowerManagement; typedef struct _virDomainPowerManagement virDomainPowerManagement;
......
...@@ -77,6 +77,7 @@ struct _virDomainNuma { ...@@ -77,6 +77,7 @@ struct _virDomainNuma {
virBitmapPtr nodeset; /* host memory nodes where this guest node resides */ virBitmapPtr nodeset; /* host memory nodes where this guest node resides */
virDomainNumatuneMemMode mode; /* memory mode selection */ virDomainNumatuneMemMode mode; /* memory mode selection */
virDomainMemoryAccess memAccess; /* shared memory access configuration */ virDomainMemoryAccess memAccess; /* shared memory access configuration */
virTristateBool discard; /* discard-data for memory-backend-file */
struct _virDomainNumaDistance { struct _virDomainNumaDistance {
unsigned int value; /* locality value for node i->j or j->i */ unsigned int value; /* locality value for node i->j or j->i */
...@@ -947,6 +948,18 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def, ...@@ -947,6 +948,18 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
VIR_FREE(tmp); 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 */ /* Parse NUMA distances info */
if (virDomainNumaDefNodeDistanceParseXML(def, ctxt, cur_cell) < 0) if (virDomainNumaDefNodeDistanceParseXML(def, ctxt, cur_cell) < 0)
goto cleanup; goto cleanup;
...@@ -967,6 +980,7 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf, ...@@ -967,6 +980,7 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf,
virDomainNumaPtr def) virDomainNumaPtr def)
{ {
virDomainMemoryAccess memAccess; virDomainMemoryAccess memAccess;
virTristateBool discard;
char *cpustr; char *cpustr;
size_t ncells = virDomainNumaGetNodeCount(def); size_t ncells = virDomainNumaGetNodeCount(def);
size_t i; size_t i;
...@@ -980,6 +994,7 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf, ...@@ -980,6 +994,7 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf,
int ndistances; int ndistances;
memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i); memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i);
discard = virDomainNumaGetNodeDiscard(def, i);
if (!(cpustr = virBitmapFormat(virDomainNumaGetNodeCpumask(def, i)))) if (!(cpustr = virBitmapFormat(virDomainNumaGetNodeCpumask(def, i))))
return -1; return -1;
...@@ -994,6 +1009,10 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf, ...@@ -994,6 +1009,10 @@ virDomainNumaDefCPUFormatXML(virBufferPtr buf,
virBufferAsprintf(buf, " memAccess='%s'", virBufferAsprintf(buf, " memAccess='%s'",
virDomainMemoryAccessTypeToString(memAccess)); virDomainMemoryAccessTypeToString(memAccess));
if (discard)
virBufferAsprintf(buf, " discard='%s'",
virTristateBoolTypeToString(discard));
ndistances = def->mem_nodes[i].ndistances; ndistances = def->mem_nodes[i].ndistances;
if (ndistances == 0) { if (ndistances == 0) {
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
...@@ -1304,6 +1323,14 @@ virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa, ...@@ -1304,6 +1323,14 @@ virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa,
} }
virTristateBool
virDomainNumaGetNodeDiscard(virDomainNumaPtr numa,
size_t node)
{
return numa->mem_nodes[node].discard;
}
unsigned long long unsigned long long
virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa, virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
size_t node) size_t node)
......
...@@ -102,6 +102,9 @@ virBitmapPtr virDomainNumaGetNodeCpumask(virDomainNumaPtr numa, ...@@ -102,6 +102,9 @@ virBitmapPtr virDomainNumaGetNodeCpumask(virDomainNumaPtr numa,
virDomainMemoryAccess virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa, virDomainMemoryAccess virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa,
size_t node) size_t node)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
virTristateBool virDomainNumaGetNodeDiscard(virDomainNumaPtr numa,
size_t node)
ATTRIBUTE_NONNULL(1);
unsigned long long virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa, unsigned long long virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
size_t node) size_t node)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
......
...@@ -750,6 +750,7 @@ virDomainNumaGetMaxCPUID; ...@@ -750,6 +750,7 @@ virDomainNumaGetMaxCPUID;
virDomainNumaGetMemorySize; virDomainNumaGetMemorySize;
virDomainNumaGetNodeCount; virDomainNumaGetNodeCount;
virDomainNumaGetNodeCpumask; virDomainNumaGetNodeCpumask;
virDomainNumaGetNodeDiscard;
virDomainNumaGetNodeDistance; virDomainNumaGetNodeDistance;
virDomainNumaGetNodeMemoryAccessMode; virDomainNumaGetNodeMemoryAccessMode;
virDomainNumaGetNodeMemorySize; virDomainNumaGetNodeMemorySize;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<page size='2048' unit='KiB' nodeset='1'/> <page size='2048' unit='KiB' nodeset='1'/>
<page size='1048576' unit='KiB' nodeset='0,2-3'/> <page size='1048576' unit='KiB' nodeset='0,2-3'/>
</hugepages> </hugepages>
<discard/>
</memoryBacking> </memoryBacking>
<vcpu placement='static'>4</vcpu> <vcpu placement='static'>4</vcpu>
<numatune> <numatune>
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
<cpu> <cpu>
<numa> <numa>
<cell id='0' cpus='0' memory='1048576' unit='KiB'/> <cell id='0' cpus='0' memory='1048576' unit='KiB'/>
<cell id='1' cpus='1' memory='1048576' unit='KiB'/> <cell id='1' cpus='1' memory='1048576' unit='KiB' discard='no'/>
<cell id='2' cpus='2' memory='1048576' unit='KiB'/> <cell id='2' cpus='2' memory='1048576' unit='KiB'/>
<cell id='3' cpus='3' memory='1048576' unit='KiB'/> <cell id='3' cpus='3' memory='1048576' unit='KiB'/>
</numa> </numa>
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
</os> </os>
<cpu> <cpu>
<numa> <numa>
<cell id='0' cpus='0' memory='262144' unit='KiB'/> <cell id='0' cpus='0' memory='262144' unit='KiB' discard='no'/>
<cell id='1' cpus='1' memory='786432' unit='KiB'/> <cell id='1' cpus='1' memory='786432' unit='KiB' discard='yes'/>
</numa> </numa>
</cpu> </cpu>
<clock offset='utc'/> <clock offset='utc'/>
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
<memballoon model='virtio'> <memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon> </memballoon>
<memory model='dimm'> <memory model='dimm' discard='no'>
<source> <source>
<nodemask>1-3</nodemask> <nodemask>1-3</nodemask>
<pagesize unit='KiB'>1048576</pagesize> <pagesize unit='KiB'>1048576</pagesize>
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
</target> </target>
<address type='dimm' slot='0'/> <address type='dimm' slot='0'/>
</memory> </memory>
<memory model='dimm' access='private'> <memory model='dimm' access='private' discard='yes'>
<target> <target>
<size unit='KiB'>524287</size> <size unit='KiB'>524287</size>
<node>0</node> <node>0</node>
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<page size='2048' unit='KiB' nodeset='1'/> <page size='2048' unit='KiB' nodeset='1'/>
<page size='1048576' unit='KiB' nodeset='0,2-3'/> <page size='1048576' unit='KiB' nodeset='0,2-3'/>
</hugepages> </hugepages>
<discard/>
</memoryBacking> </memoryBacking>
<vcpu placement='static'>4</vcpu> <vcpu placement='static'>4</vcpu>
<numatune> <numatune>
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
<cpu> <cpu>
<numa> <numa>
<cell id='0' cpus='0' memory='1048576' unit='KiB'/> <cell id='0' cpus='0' memory='1048576' unit='KiB'/>
<cell id='1' cpus='1' memory='1048576' unit='KiB'/> <cell id='1' cpus='1' memory='1048576' unit='KiB' discard='no'/>
<cell id='2' cpus='2' memory='1048576' unit='KiB'/> <cell id='2' cpus='2' memory='1048576' unit='KiB'/>
<cell id='3' cpus='3' memory='1048576' unit='KiB'/> <cell id='3' cpus='3' memory='1048576' unit='KiB'/>
</numa> </numa>
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
</os> </os>
<cpu> <cpu>
<numa> <numa>
<cell id='0' cpus='0' memory='262144' unit='KiB'/> <cell id='0' cpus='0' memory='262144' unit='KiB' discard='no'/>
<cell id='1' cpus='1' memory='786432' unit='KiB'/> <cell id='1' cpus='1' memory='786432' unit='KiB' discard='yes'/>
</numa> </numa>
</cpu> </cpu>
<clock offset='utc'/> <clock offset='utc'/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册