|
|
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 |
|