Note that due to alignment of the memory chunks added via memory
hotplug the full size allocation specified by this element may be
impossible to achieve.
- <span class='since'>Since 1.2.14</span>
+ <span class='since'>Since 1.2.14 supported by the QEMU driver.</span>
</dd>
<dt><code>currentMemory</code></dt>
if (qemuDomainAlignMemorySizes(def) < 0)
goto error;
- /* Set '-m MB' based on maxmem, because the lower 'memory' limit
- * is set post-startup using the balloon driver. If balloon driver
- * is not supported, then they're out of luck anyway. Update the
- * XML to reflect our rounding.
- */
virCommandAddArg(cmd, "-m");
- virCommandAddArgFormat(cmd, "%llu", virDomainDefGetMemoryInitial(def) / 1024);
+
+ if (def->mem.max_memory) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PC_DIMM)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("memory hotplug isn't supported by this QEMU binary"));
+ goto error;
+ }
+
+ /* due to guest support, qemu would silently enable NUMA with one node
+ * once the memory hotplug backend is enabled. To avoid possible
+ * confusion we will enforce user originated numa configuration along
+ * with memory hotplug. */
+ if (virDomainNumaGetNodeCount(def->numa) == 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("At least one numa node has to be configured when "
+ "enabling memory hotplug"));
+ goto error;
+ }
+
+ /* Use the 'k' suffix to let qemu handle the units */
+ virCommandAddArgFormat(cmd, "size=%lluk,slots=%u,maxmem=%lluk",
+ virDomainDefGetMemoryInitial(def),
+ def->mem.memory_slots,
+ def->mem.max_memory);
+
+ } else {
+ virCommandAddArgFormat(cmd, "%llu", virDomainDefGetMemoryInitial(def) / 1024);
+ }
if (def->mem.nhugepages && !virDomainNumaGetNodeCount(def->numa)) {
const long system_page_size = virGetSystemPageSizeKB();
VIR_DOMAIN_INPUT_BUS_USB) < 0)
return -1;
- /* memory hotplug tunables are not supported by this driver */
- if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
- return -1;
-
return 0;
}
mem = virDomainDefGetMemoryInitial(def);
virDomainDefSetMemoryInitial(def, VIR_ROUND_UP(mem, 1024));
+ /* Align maximum memory size. QEMU requires rounding to next 4KiB block.
+ * We'll take the "traditional" path and round it to 1MiB*/
+ def->mem.max_memory = VIR_ROUND_UP(def->mem.max_memory, 1024);
+
return 0;
}
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <maxMemory slots='9' unit='KiB'>1233456789</maxMemory>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc \
+-m size=219136k,slots=16,maxmem=1099511627776k \
+-smp 2 -numa node,nodeid=0,cpus=0-1,mem=214 \
+-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-usb -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <maxMemory slots='16' unit='KiB'>1099511627776</maxMemory>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ <numa>
+ <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
DO_TEST_PARSE_ERROR("shmem-msi-only", NONE);
DO_TEST("cpu-host-passthrough-features", QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST);
+ DO_TEST_FAILURE("memory-hotplug-nonuma", QEMU_CAPS_DEVICE_PC_DIMM);
+ DO_TEST_FAILURE("memory-hotplug", NONE);
+ DO_TEST("memory-hotplug", QEMU_CAPS_DEVICE_PC_DIMM, QEMU_CAPS_NUMA);
+
virObjectUnref(driver.config);
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
DO_TEST("smbios");
DO_TEST("aarch64-aavmf-virtio-mmio");
+ DO_TEST("memory-hotplug");
+ DO_TEST("memory-hotplug-nonuma");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);