]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Pre-calculate initial memory size instead of always calculating it
authorPeter Krempa <pkrempa@redhat.com>
Thu, 13 Aug 2015 14:39:28 +0000 (16:39 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 22 Sep 2015 14:09:28 +0000 (16:09 +0200)
Add 'initial_memory' member to struct virDomainMemtune so that the
memory size can be pre-calculated once instead of inferring it always
again and again.

Separating of the fields will also allow finer granularity of decisions
in later patches where it will allow to keep the old initial memory
value in cases where we are handling incomming migration from older
versions that did not always update the size from NUMA as the code did
previously.

The change also requires modification of the qemu memory alignment
function since at the point where we are modifying the size of NUMA
nodes the total size needs to be recalculated too.

The refactoring done in this patch also fixes a crash in the hyperv
driver that did not properly initialize def->numa and thus
virDomainNumaGetMemorySize(def->numa) crashed.

In summary this patch should have no functional impact at this point.

src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_domain.c

index 0f58f58f3fc7f52aa5c27aca66f14b7a9d3eceae..2cc03d92acedf55a94ca317525a2233da94f45c8 100644 (file)
@@ -3728,6 +3728,15 @@ virDomainDefRemoveDuplicateMetadata(virDomainDefPtr def)
 static int
 virDomainDefPostParseMemory(virDomainDefPtr def)
 {
+    size_t i;
+
+    if ((def->mem.initial_memory = virDomainNumaGetMemorySize(def->numa)) == 0) {
+        def->mem.initial_memory = def->mem.total_memory;
+
+        for (i = 0; i < def->nmems; i++)
+            def->mem.initial_memory -= def->mems[i]->size;
+    }
+
     if (virDomainDefGetMemoryInitial(def) == 0) {
         virReportError(VIR_ERR_XML_ERROR, "%s",
                        _("Memory size must be specified via <memory> or in the "
@@ -7699,19 +7708,7 @@ virDomainDefHasMemoryHotplug(const virDomainDef *def)
 unsigned long long
 virDomainDefGetMemoryInitial(virDomainDefPtr def)
 {
-    unsigned long long ret;
-    size_t i;
-
-    /* return NUMA memory size total in case numa is enabled */
-    if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0) {
-        return ret;
-    } else {
-        ret = def->mem.total_memory;
-        for (i = 0; i < def->nmems; i++)
-            ret -= def->mems[i]->size;
-    }
-
-    return def->mem.total_memory;
+    return def->mem.initial_memory;
 }
 
 
@@ -7720,13 +7717,30 @@ virDomainDefGetMemoryInitial(virDomainDefPtr def)
  * @def: domain definition
  * @size: size to set
  *
- * Sets the total memory size in @def.
+ * Sets the total memory size in @def. This function should be used only by
+ * hypervisors that don't support memory hotplug.
  */
 void
 virDomainDefSetMemoryTotal(virDomainDefPtr def,
                            unsigned long long size)
 {
     def->mem.total_memory = size;
+    def->mem.initial_memory = size;
+}
+
+
+/**
+ * virDomainDefSetMemoryInitial:
+ * @def: domain definition
+ * @size: size to set
+ *
+ * Sets the initial memory size (without memory modules) in @def.
+ */
+void
+virDomainDefSetMemoryInitial(virDomainDefPtr def,
+                             unsigned long long size)
+{
+    def->mem.initial_memory = size;
 }
 
 
@@ -7744,12 +7758,10 @@ virDomainDefGetMemoryActual(virDomainDefPtr def)
     unsigned long long ret;
     size_t i;
 
-    if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0) {
-        for (i = 0; i < def->nmems; i++)
-            ret += def->mems[i]->size;
-    } else {
-        ret = def->mem.total_memory;
-    }
+    ret = def->mem.initial_memory;
+
+    for (i = 0; i < def->nmems; i++)
+        ret += def->mems[i]->size;
 
     return ret;
 }
index 74c29bd7fdb8c44e10e45b3d56e304bcafa3fe22..ab250bd1be6b38ec8ee3335998c9be557953a694 100644 (file)
@@ -2145,6 +2145,8 @@ struct _virDomainMemtune {
     /* total memory size including memory modules in kibibytes, this field
      * should be accessed only via accessors */
     unsigned long long total_memory;
+    /* initial memory size in kibibytes = total_memory excluding memory modules*/
+    unsigned long long initial_memory;
     unsigned long long cur_balloon; /* in kibibytes, capped at ulong thanks
                                        to virDomainGetInfo */
 
@@ -2324,6 +2326,7 @@ struct _virDomainDef {
 
 unsigned long long virDomainDefGetMemoryInitial(virDomainDefPtr def);
 void virDomainDefSetMemoryTotal(virDomainDefPtr def, unsigned long long size);
+void virDomainDefSetMemoryInitial(virDomainDefPtr def, unsigned long long size);
 unsigned long long virDomainDefGetMemoryActual(virDomainDefPtr def);
 bool virDomainDefHasMemoryHotplug(const virDomainDef *def);
 
index d31687d12bfc9771c4c68f7755d82ab42205167e..c87efa1d075b57ef1498a95833167758351c0ad7 100644 (file)
@@ -227,6 +227,7 @@ virDomainDefParseFile;
 virDomainDefParseNode;
 virDomainDefParseString;
 virDomainDefPostParse;
+virDomainDefSetMemoryInitial;
 virDomainDefSetMemoryTotal;
 virDomainDeleteConfig;
 virDomainDeviceAddressIsValid;
index e3cd17f46377d6d487aac873d6b41da38d95f1de..9f40276d6405ee01c942f4aecc56cec9497369c6 100644 (file)
@@ -3374,6 +3374,7 @@ qemuDomainGetMemorySizeAlignment(virDomainDefPtr def ATTRIBUTE_UNUSED)
 int
 qemuDomainAlignMemorySizes(virDomainDefPtr def)
 {
+    unsigned long long initialmem = 0;
     unsigned long long mem;
     unsigned long long align = qemuDomainGetMemorySizeAlignment(def);
     size_t ncells = virDomainNumaGetNodeCount(def->numa);
@@ -3381,13 +3382,17 @@ qemuDomainAlignMemorySizes(virDomainDefPtr def)
 
     /* align NUMA cell sizes if relevant */
     for (i = 0; i < ncells; i++) {
-        mem = virDomainNumaGetNodeMemorySize(def->numa, i);
-        virDomainNumaSetNodeMemorySize(def->numa, i, VIR_ROUND_UP(mem, align));
+        mem = VIR_ROUND_UP(virDomainNumaGetNodeMemorySize(def->numa, i), align);
+        initialmem += mem;
+        virDomainNumaSetNodeMemorySize(def->numa, i, mem);
     }
 
-    /* align initial memory size */
-    mem = virDomainDefGetMemoryInitial(def);
-    virDomainDefSetMemoryTotal(def, VIR_ROUND_UP(mem, align));
+    /* align initial memory size, if NUMA is present calculate it as total of
+     * individual aligned NUMA node sizes */
+    if (initialmem == 0)
+        initialmem = VIR_ROUND_UP(virDomainDefGetMemoryInitial(def), align);
+
+    virDomainDefSetMemoryInitial(def, initialmem);
 
     def->mem.max_memory = VIR_ROUND_UP(def->mem.max_memory, align);