diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0f58f58f3f..2cc03d92ac 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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 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; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 74c29bd7fd..ab250bd1be 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -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); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d31687d12b..c87efa1d07 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -227,6 +227,7 @@ virDomainDefParseFile; virDomainDefParseNode; virDomainDefParseString; virDomainDefPostParse; +virDomainDefSetMemoryInitial; virDomainDefSetMemoryTotal; virDomainDeleteConfig; virDomainDeviceAddressIsValid; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e3cd17f463..9f40276d64 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -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);