]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Introduce memoryBacking/discard
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 11 May 2018 13:08:53 +0000 (15:08 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 14 May 2018 07:42:20 +0000 (09:42 +0200)
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 <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
13 files changed:
docs/formatdomain.html.in
docs/schemas/cputypes.rng
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/numa_conf.c
src/conf/numa_conf.h
src/libvirt_private.syms
tests/qemuxml2argvdata/hugepages-pages.xml
tests/qemuxml2argvdata/hugepages-pages3.xml
tests/qemuxml2argvdata/hugepages-pages7.xml
tests/qemuxml2xmloutdata/hugepages-pages.xml
tests/qemuxml2xmloutdata/hugepages-pages3.xml

index 072f9a0fdcb58840142de2a9a14039dd41d61300..80172c18d0c25ee94fe4c46bb7943f8d1f32c6c6 100644 (file)
     &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;
          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>
 
 
 &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;
   ...
       <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>
index c45b6dfb28adf7ffe82ac4c429dadf423609e53a..1f1e0e36d59bf60ebd0a349f720a9001ded8fd17 100644 (file)
           </choice>
         </attribute>
       </optional>
+      <optional>
+        <attribute name="discard">
+          <ref name="virYesNo"/>
+        </attribute>
+      </optional>
       <optional>
         <element name="distances">
           <oneOrMore>
index 8c446ca41856901e22722c19500c0a65360821d4..13af5b74a4988ecd4076e5235e5c6dcdbaef9f53 100644 (file)
                 </attribute>
               </element>
             </optional>
+            <optional>
+              <element name="discard">
+                <empty/>
+              </element>
+            </optional>
           </interleave>
         </element>
       </optional>
           </choice>
         </attribute>
       </optional>
+      <optional>
+        <attribute name="discard">
+          <ref name="virYesNo"/>
+        </attribute>
+      </optional>
       <interleave>
         <optional>
           <ref name="memorydev-source"/>
index 6786d81c9b0a6014d5496661c68b3958af641417..86229db654f98da12ae2d3e857c64deb850e22da 100644 (file)
@@ -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;
index 15d228ba9e62780bd6192cb01c25f14c7cf8665d..07d04fb2f986db29b908dbea8c61319dbd9a67d5 100644 (file)
@@ -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;
index 9307dd93d3d47ceab9bbdc530a131b81e1548100..97a3ca485d178cad3e5bfe9d469673737b422de0 100644 (file)
@@ -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)
index 7947fdb21923bc2c80b42fb27afc46b73cf1551b..85269be5651284216b39062ecdf38acf9cbf517a 100644 (file)
@@ -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);
index 5fea1bca41d9a58eb8002664be1c26995ddcd143..d28a751ebd1ae836e4303bf17533f19d7c83d5a1 100644 (file)
@@ -750,6 +750,7 @@ virDomainNumaGetMaxCPUID;
 virDomainNumaGetMemorySize;
 virDomainNumaGetNodeCount;
 virDomainNumaGetNodeCpumask;
+virDomainNumaGetNodeDiscard;
 virDomainNumaGetNodeDistance;
 virDomainNumaGetNodeMemoryAccessMode;
 virDomainNumaGetNodeMemorySize;
index f9270782d4fe12d564363dd422ef27d115b79097..cba83e754c295939d167da9596d898e366ca2b17 100644 (file)
@@ -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>
index 3d3b3f3cc3fcb0e3a138f8291edfe3de6dbc937a..147acc4c95a627742b985b9f08fed42198742232 100644 (file)
@@ -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'/>
index d75cf5afa343c75eab85417efc43aa735d72b1ab..28c72f85a72d644bb196623b4644aa984fdafe1d 100644 (file)
@@ -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>
index 498610a217fed837e62f6fa2d455a7e048a2ca1d..292454588e556536429f23bdfdc57b6bfda4b053 100644 (file)
@@ -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>
index be21c3eddd9332f09b40da7f20fa706a61cf712d..90e6efa5eaca5e48f6d1f2b558d49e2142d84a92 100644 (file)
@@ -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'/>