Blame SOURCES/libvirt-conf-Pre-calculate-initial-memory-size-instead-of-always-calculating-it.patch

7a3408
From 26895224315526096a1a0e3adf36ef1fadc17727 Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <26895224315526096a1a0e3adf36ef1fadc17727@dist-git>
7a3408
From: Peter Krempa <pkrempa@redhat.com>
7a3408
Date: Tue, 22 Sep 2015 16:59:44 +0200
7a3408
Subject: [PATCH] conf: Pre-calculate initial memory size instead of always
7a3408
 calculating it
7a3408
7a3408
https://bugzilla.redhat.com/show_bug.cgi?id=1252685
7a3408
7a3408
Add 'initial_memory' member to struct virDomainMemtune so that the
7a3408
memory size can be pre-calculated once instead of inferring it always
7a3408
again and again.
7a3408
7a3408
Separating of the fields will also allow finer granularity of decisions
7a3408
in later patches where it will allow to keep the old initial memory
7a3408
value in cases where we are handling incomming migration from older
7a3408
versions that did not always update the size from NUMA as the code did
7a3408
previously.
7a3408
7a3408
The change also requires modification of the qemu memory alignment
7a3408
function since at the point where we are modifying the size of NUMA
7a3408
nodes the total size needs to be recalculated too.
7a3408
7a3408
The refactoring done in this patch also fixes a crash in the hyperv
7a3408
driver that did not properly initialize def->numa and thus
7a3408
virDomainNumaGetMemorySize(def->numa) crashed.
7a3408
7a3408
In summary this patch should have no functional impact at this point.
7a3408
7a3408
(cherry picked from commit 403e86067d5cb3a6fd8583cb5b08121151bd4d9f)
7a3408
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 src/conf/domain_conf.c   | 52 +++++++++++++++++++++++++++++-------------------
7a3408
 src/conf/domain_conf.h   |  3 +++
7a3408
 src/libvirt_private.syms |  1 +
7a3408
 src/qemu/qemu_domain.c   | 15 +++++++++-----
7a3408
 4 files changed, 46 insertions(+), 25 deletions(-)
7a3408
7a3408
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
7a3408
index b28daa6..3625310 100644
7a3408
--- a/src/conf/domain_conf.c
7a3408
+++ b/src/conf/domain_conf.c
7a3408
@@ -3642,6 +3642,15 @@ virDomainDefRemoveDuplicateMetadata(virDomainDefPtr def)
7a3408
 static int
7a3408
 virDomainDefPostParseMemory(virDomainDefPtr def)
7a3408
 {
7a3408
+    size_t i;
7a3408
+
7a3408
+    if ((def->mem.initial_memory = virDomainNumaGetMemorySize(def->numa)) == 0) {
7a3408
+        def->mem.initial_memory = def->mem.total_memory;
7a3408
+
7a3408
+        for (i = 0; i < def->nmems; i++)
7a3408
+            def->mem.initial_memory -= def->mems[i]->size;
7a3408
+    }
7a3408
+
7a3408
     if (virDomainDefGetMemoryInitial(def) == 0) {
7a3408
         virReportError(VIR_ERR_XML_ERROR, "%s",
7a3408
                        _("Memory size must be specified via <memory> or in the "
7a3408
@@ -7665,19 +7674,7 @@ virDomainDefHasMemoryHotplug(const virDomainDef *def)
7a3408
 unsigned long long
7a3408
 virDomainDefGetMemoryInitial(virDomainDefPtr def)
7a3408
 {
7a3408
-    unsigned long long ret;
7a3408
-    size_t i;
7a3408
-
7a3408
-    /* return NUMA memory size total in case numa is enabled */
7a3408
-    if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0) {
7a3408
-        return ret;
7a3408
-    } else {
7a3408
-        ret = def->mem.total_memory;
7a3408
-        for (i = 0; i < def->nmems; i++)
7a3408
-            ret -= def->mems[i]->size;
7a3408
-    }
7a3408
-
7a3408
-    return def->mem.total_memory;
7a3408
+    return def->mem.initial_memory;
7a3408
 }
7a3408
 
7a3408
 
7a3408
@@ -7686,13 +7683,30 @@ virDomainDefGetMemoryInitial(virDomainDefPtr def)
7a3408
  * @def: domain definition
7a3408
  * @size: size to set
7a3408
  *
7a3408
- * Sets the total memory size in @def.
7a3408
+ * Sets the total memory size in @def. This function should be used only by
7a3408
+ * hypervisors that don't support memory hotplug.
7a3408
  */
7a3408
 void
7a3408
 virDomainDefSetMemoryTotal(virDomainDefPtr def,
7a3408
                            unsigned long long size)
7a3408
 {
7a3408
     def->mem.total_memory = size;
7a3408
+    def->mem.initial_memory = size;
7a3408
+}
7a3408
+
7a3408
+
7a3408
+/**
7a3408
+ * virDomainDefSetMemoryInitial:
7a3408
+ * @def: domain definition
7a3408
+ * @size: size to set
7a3408
+ *
7a3408
+ * Sets the initial memory size (without memory modules) in @def.
7a3408
+ */
7a3408
+void
7a3408
+virDomainDefSetMemoryInitial(virDomainDefPtr def,
7a3408
+                             unsigned long long size)
7a3408
+{
7a3408
+    def->mem.initial_memory = size;
7a3408
 }
7a3408
 
7a3408
 
7a3408
@@ -7710,12 +7724,10 @@ virDomainDefGetMemoryActual(virDomainDefPtr def)
7a3408
     unsigned long long ret;
7a3408
     size_t i;
7a3408
 
7a3408
-    if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0) {
7a3408
-        for (i = 0; i < def->nmems; i++)
7a3408
-            ret += def->mems[i]->size;
7a3408
-    } else {
7a3408
-        ret = def->mem.total_memory;
7a3408
-    }
7a3408
+    ret = def->mem.initial_memory;
7a3408
+
7a3408
+    for (i = 0; i < def->nmems; i++)
7a3408
+        ret += def->mems[i]->size;
7a3408
 
7a3408
     return ret;
7a3408
 }
7a3408
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
7a3408
index 8099450..61bf963 100644
7a3408
--- a/src/conf/domain_conf.h
7a3408
+++ b/src/conf/domain_conf.h
7a3408
@@ -2109,6 +2109,8 @@ struct _virDomainMemtune {
7a3408
     /* total memory size including memory modules in kibibytes, this field
7a3408
      * should be accessed only via accessors */
7a3408
     unsigned long long total_memory;
7a3408
+    /* initial memory size in kibibytes = total_memory excluding memory modules*/
7a3408
+    unsigned long long initial_memory;
7a3408
     unsigned long long cur_balloon; /* in kibibytes, capped at ulong thanks
7a3408
                                        to virDomainGetInfo */
7a3408
 
7a3408
@@ -2288,6 +2290,7 @@ struct _virDomainDef {
7a3408
 
7a3408
 unsigned long long virDomainDefGetMemoryInitial(virDomainDefPtr def);
7a3408
 void virDomainDefSetMemoryTotal(virDomainDefPtr def, unsigned long long size);
7a3408
+void virDomainDefSetMemoryInitial(virDomainDefPtr def, unsigned long long size);
7a3408
 unsigned long long virDomainDefGetMemoryActual(virDomainDefPtr def);
7a3408
 bool virDomainDefHasMemoryHotplug(const virDomainDef *def);
7a3408
 
7a3408
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
7a3408
index b1b59b2..16ae24f 100644
7a3408
--- a/src/libvirt_private.syms
7a3408
+++ b/src/libvirt_private.syms
7a3408
@@ -225,6 +225,7 @@ virDomainDefParseFile;
7a3408
 virDomainDefParseNode;
7a3408
 virDomainDefParseString;
7a3408
 virDomainDefPostParse;
7a3408
+virDomainDefSetMemoryInitial;
7a3408
 virDomainDefSetMemoryTotal;
7a3408
 virDomainDeleteConfig;
7a3408
 virDomainDeviceAddressIsValid;
7a3408
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
7a3408
index 67c2bb0..77f3d6a 100644
7a3408
--- a/src/qemu/qemu_domain.c
7a3408
+++ b/src/qemu/qemu_domain.c
7a3408
@@ -3171,6 +3171,7 @@ qemuDomainGetMemorySizeAlignment(virDomainDefPtr def ATTRIBUTE_UNUSED)
7a3408
 int
7a3408
 qemuDomainAlignMemorySizes(virDomainDefPtr def)
7a3408
 {
7a3408
+    unsigned long long initialmem = 0;
7a3408
     unsigned long long mem;
7a3408
     unsigned long long align = qemuDomainGetMemorySizeAlignment(def);
7a3408
     size_t ncells = virDomainNumaGetNodeCount(def->numa);
7a3408
@@ -3178,13 +3179,17 @@ qemuDomainAlignMemorySizes(virDomainDefPtr def)
7a3408
 
7a3408
     /* align NUMA cell sizes if relevant */
7a3408
     for (i = 0; i < ncells; i++) {
7a3408
-        mem = virDomainNumaGetNodeMemorySize(def->numa, i);
7a3408
-        virDomainNumaSetNodeMemorySize(def->numa, i, VIR_ROUND_UP(mem, align));
7a3408
+        mem = VIR_ROUND_UP(virDomainNumaGetNodeMemorySize(def->numa, i), align);
7a3408
+        initialmem += mem;
7a3408
+        virDomainNumaSetNodeMemorySize(def->numa, i, mem);
7a3408
     }
7a3408
 
7a3408
-    /* align initial memory size */
7a3408
-    mem = virDomainDefGetMemoryInitial(def);
7a3408
-    virDomainDefSetMemoryTotal(def, VIR_ROUND_UP(mem, align));
7a3408
+    /* align initial memory size, if NUMA is present calculate it as total of
7a3408
+     * individual aligned NUMA node sizes */
7a3408
+    if (initialmem == 0)
7a3408
+        initialmem = VIR_ROUND_UP(virDomainDefGetMemoryInitial(def), align);
7a3408
+
7a3408
+    virDomainDefSetMemoryInitial(def, initialmem);
7a3408
 
7a3408
     def->mem.max_memory = VIR_ROUND_UP(def->mem.max_memory, align);
7a3408
 
7a3408
-- 
7a3408
2.5.3
7a3408