提交 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 @@
&lt;source type="file|anonymous"/&gt;
&lt;access mode="shared|private"/&gt;
&lt;allocation mode="immediate|ondemand"/&gt;
&lt;discard/&gt;
&lt;/memoryBacking&gt;
...
&lt;/domain&gt;
......@@ -1070,6 +1071,14 @@
numa node by <code>memAccess</code></dd>
<dt><code>allocation</code></dt>
<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>
......@@ -1608,7 +1617,7 @@
&lt;cpu&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;/numa&gt;
...
......@@ -1634,6 +1643,13 @@
<code>memAccess</code> 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 <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>
......@@ -7883,7 +7899,7 @@ qemu-kvm -net nic,model=? /dev/null
<pre>
...
&lt;devices&gt;
&lt;memory model='dimm' access='private'&gt;
&lt;memory model='dimm' access='private' discard='yes'&gt;
&lt;target&gt;
&lt;size unit='KiB'&gt;524287&lt;/size&gt;
&lt;node&gt;0&lt;/node&gt;
......@@ -7937,6 +7953,20 @@ qemu-kvm -net nic,model=? /dev/null
</p>
</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>
<dd>
<p>
......
......@@ -129,6 +129,11 @@
</choice>
</attribute>
</optional>
<optional>
<attribute name="discard">
<ref name="virYesNo"/>
</attribute>
</optional>
<optional>
<element name="distances">
<oneOrMore>
......
......@@ -633,6 +633,11 @@
</attribute>
</element>
</optional>
<optional>
<element name="discard">
<empty/>
</element>
</optional>
</interleave>
</element>
</optional>
......@@ -5124,6 +5129,11 @@
</choice>
</attribute>
</optional>
<optional>
<attribute name="discard">
<ref name="virYesNo"/>
</attribute>
</optional>
<interleave>
<optional>
<ref name="memorydev-source"/>
......
......@@ -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, "<allocation mode='%s'/>\n",
virDomainMemoryAllocationTypeToString(mem->allocation));
if (mem->discard)
virBufferAddLit(&childBuf, "<discard/>\n");
if (virXMLFormatElement(buf, "memoryBacking", NULL, &childBuf) < 0)
goto cleanup;
......
......@@ -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;
......
......@@ -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)
......
......@@ -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);
......
......@@ -750,6 +750,7 @@ virDomainNumaGetMaxCPUID;
virDomainNumaGetMemorySize;
virDomainNumaGetNodeCount;
virDomainNumaGetNodeCpumask;
virDomainNumaGetNodeDiscard;
virDomainNumaGetNodeDistance;
virDomainNumaGetNodeMemoryAccessMode;
virDomainNumaGetNodeMemorySize;
......
......@@ -8,6 +8,7 @@
<page size='2048' unit='KiB' nodeset='1'/>
<page size='1048576' unit='KiB' nodeset='0,2-3'/>
</hugepages>
<discard/>
</memoryBacking>
<vcpu placement='static'>4</vcpu>
<numatune>
......@@ -21,7 +22,7 @@
<cpu>
<numa>
<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='3' cpus='3' memory='1048576' unit='KiB'/>
</numa>
......
......@@ -15,8 +15,8 @@
</os>
<cpu>
<numa>
<cell id='0' cpus='0' memory='262144' unit='KiB'/>
<cell id='1' cpus='1' memory='786432' unit='KiB'/>
<cell id='0' cpus='0' memory='262144' unit='KiB' discard='no'/>
<cell id='1' cpus='1' memory='786432' unit='KiB' discard='yes'/>
</numa>
</cpu>
<clock offset='utc'/>
......
......@@ -43,7 +43,7 @@
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon>
<memory model='dimm'>
<memory model='dimm' discard='no'>
<source>
<nodemask>1-3</nodemask>
<pagesize unit='KiB'>1048576</pagesize>
......@@ -54,7 +54,7 @@
</target>
<address type='dimm' slot='0'/>
</memory>
<memory model='dimm' access='private'>
<memory model='dimm' access='private' discard='yes'>
<target>
<size unit='KiB'>524287</size>
<node>0</node>
......
......@@ -8,6 +8,7 @@
<page size='2048' unit='KiB' nodeset='1'/>
<page size='1048576' unit='KiB' nodeset='0,2-3'/>
</hugepages>
<discard/>
</memoryBacking>
<vcpu placement='static'>4</vcpu>
<numatune>
......@@ -21,7 +22,7 @@
<cpu>
<numa>
<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='3' cpus='3' memory='1048576' unit='KiB'/>
</numa>
......
......@@ -15,8 +15,8 @@
</os>
<cpu>
<numa>
<cell id='0' cpus='0' memory='262144' unit='KiB'/>
<cell id='1' cpus='1' memory='786432' unit='KiB'/>
<cell id='0' cpus='0' memory='262144' unit='KiB' discard='no'/>
<cell id='1' cpus='1' memory='786432' unit='KiB' discard='yes'/>
</numa>
</cpu>
<clock offset='utc'/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册