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 "
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;
}
* @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;
}
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;
}
/* 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 */
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);
virDomainDefParseNode;
virDomainDefParseString;
virDomainDefPostParse;
+virDomainDefSetMemoryInitial;
virDomainDefSetMemoryTotal;
virDomainDeleteConfig;
virDomainDeviceAddressIsValid;
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);
/* 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);