]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Implement setup of memory hotplug parameters
authorPeter Krempa <pkrempa@redhat.com>
Mon, 6 Oct 2014 12:18:37 +0000 (14:18 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 23 Mar 2015 13:25:14 +0000 (14:25 +0100)
To enable memory hotplug the maximum memory size and slot count need to
be specified. As qemu supports now other units than mebibytes when
specifying memory, use the new interface in this case.

docs/formatdomain.html.in
src/qemu/qemu_command.c
src/qemu/qemu_domain.c
tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-nonuma.xml [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmltest.c

index cc80efa73d01a18a9f721bffa63afd487e230790..2b1833dfd7bd7a810e939b306d9c84c09fc2af0b 100644 (file)
         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>
index 04e7bcc85ffffefd24e89952fd72cd4d6dd82ea8..3491f5ff644323a28f9b516fb83ba6ebca477b87 100644 (file)
@@ -8492,13 +8492,35 @@ qemuBuildCommandLine(virConnectPtr conn,
     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();
index 8baa0402be1f42e74c116738fa23b89c7ba7e919..aa0e779229508a60ae40e3df77b94545afad0b8d 100644 (file)
@@ -1052,10 +1052,6 @@ qemuDomainDefPostParse(virDomainDefPtr def,
                                   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;
 }
 
@@ -2906,5 +2902,9 @@ qemuDomainAlignMemorySizes(virDomainDefPtr def)
     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;
 }
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-nonuma.xml b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-nonuma.xml
new file mode 100644 (file)
index 0000000..5c807ed
--- /dev/null
@@ -0,0 +1,22 @@
+<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>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug.args b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug.args
new file mode 100644 (file)
index 0000000..6c26586
--- /dev/null
@@ -0,0 +1,6 @@
+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
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug.xml b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug.xml
new file mode 100644 (file)
index 0000000..567a662
--- /dev/null
@@ -0,0 +1,34 @@
+<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>
index fcf52187305432acfdb1ca6cb2ab3c3d5e71a646..387b3494a2a8ab36abf8eaeb043e69fd2155dfec 100644 (file)
@@ -1543,6 +1543,10 @@ mymain(void)
     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);
index 346a0251a67de08c308a932fc0cea8e5dedd221c..9f1fc8ff54d3fabdf4771ae9193e5477301b236d 100644 (file)
@@ -428,6 +428,9 @@ mymain(void)
     DO_TEST("smbios");
     DO_TEST("aarch64-aavmf-virtio-mmio");
 
+    DO_TEST("memory-hotplug");
+    DO_TEST("memory-hotplug-nonuma");
+
     virObjectUnref(driver.caps);
     virObjectUnref(driver.xmlopt);