d89b3e
From c0af84c532e72d42a66059998ef7f03dcb0d6bd1 Mon Sep 17 00:00:00 2001
d89b3e
Message-Id: <c0af84c532e72d42a66059998ef7f03dcb0d6bd1@dist-git>
d89b3e
From: Michal Privoznik <mprivozn@redhat.com>
d89b3e
Date: Mon, 23 Feb 2015 08:20:03 +0100
d89b3e
Subject: [PATCH] qemuBuildNumaArgStr: Use memory-backend-ram more wisely
d89b3e
d89b3e
RHEL-7.2: https://bugzilla.redhat.com/show_bug.cgi?id=1191567
d89b3e
RHEL-7.1.z: https://bugzilla.redhat.com/show_bug.cgi?id=1194982
d89b3e
d89b3e
So, when building the '-numa' command line, the qemuBuildNumaArgStr()
d89b3e
function does quite a lot of checks to chose the best backend, or to
d89b3e
check if one is in fact needed. However, it returned that backend is
d89b3e
needed even for this little fella:
d89b3e
d89b3e
  <numatune>
d89b3e
    <memory mode="strict" nodeset="0,2"/>
d89b3e
  </numatune>
d89b3e
d89b3e
This can be guaranteed via CGroups entirely, there's no need to use
d89b3e
memory-backend-ram to let qemu know where to get memory from. Well, as
d89b3e
long as there's no <memnode/> element, which explicitly requires the
d89b3e
backend. Long story short, we wouldn't have to care, as qemu works
d89b3e
either way. However, the problem is migration (as always). Previously,
d89b3e
libvirt would have started qemu with:
d89b3e
d89b3e
  -numa node,memory=X
d89b3e
d89b3e
in this case and restricted memory placement in CGroups. Today, libvirt
d89b3e
creates more complicated command line:
d89b3e
d89b3e
  -object memory-backend-ram,id=ram-node0,size=X
d89b3e
  -numa node,memdev=ram-node0
d89b3e
d89b3e
Again, one wouldn't find anything wrong with these two approaches.
d89b3e
Both work just fine. Unless you try to migrated from the older libvirt
d89b3e
into the newer one. These two approaches are, unfortunately, not
d89b3e
compatible. My suggestion is, in order to allow users to migrate, lets
d89b3e
use the older approach for as long as the newer one is not needed.
d89b3e
d89b3e
Moreover, this partly cherry-picks
d89b3e
b92a0037103efc15639dee9562866dbaffe302fb too. Especially the tests,
d89b3e
which need to be fixed too. We can't mix the bare -numa and
d89b3e
memory-backend-ram on the command line.
d89b3e
d89b3e
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d89b3e
(cherry picked from commit 7832fac84741d65e851dbdbfaf474785cbfdcf3c)
d89b3e
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d89b3e
d89b3e
Conflicts:
d89b3e
	src/qemu/qemu_command.c: The code is totally rewritten
d89b3e
        upstream (esp. after memory hotplug).
d89b3e
        tests/qemuxml2argvtest.c: Context, some tests were not
d89b3e
        introduced yet.
d89b3e
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
d89b3e
---
d89b3e
 src/qemu/qemu_command.c                            | 35 +++++++++++---------
d89b3e
 .../qemuxml2argv-cputune-numatune.args             |  5 +++
d89b3e
 .../qemuxml2argv-cputune-numatune.xml              | 37 ++++++++++++++++++++++
d89b3e
 .../qemuxml2argv-hugepages-pages3.args             |  3 +-
d89b3e
 .../qemuxml2argv-numatune-auto-prefer.args         |  5 +++
d89b3e
 .../qemuxml2argv-numatune-memnode-no-memory.args   |  3 +-
d89b3e
 tests/qemuxml2argvtest.c                           |  6 ++++
d89b3e
 7 files changed, 77 insertions(+), 17 deletions(-)
d89b3e
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args
d89b3e
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml
d89b3e
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args
d89b3e
d89b3e
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
d89b3e
index db0c324..a9cb7a3 100644
d89b3e
--- a/src/qemu/qemu_command.c
d89b3e
+++ b/src/qemu/qemu_command.c
d89b3e
@@ -6540,22 +6540,27 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
d89b3e
     char *nodemask = NULL;
d89b3e
     char *mem_path = NULL;
d89b3e
     int ret = -1;
d89b3e
+    bool useNodemask = false;
d89b3e
 
d89b3e
-    if (virDomainNumatuneHasPerNodeBinding(def->numatune) &&
d89b3e
-        !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
d89b3e
-          virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE))) {
d89b3e
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
d89b3e
-                       _("Per-node memory binding is not supported "
d89b3e
-                         "with this QEMU"));
d89b3e
-        goto cleanup;
d89b3e
+    if (virDomainNumatuneHasPerNodeBinding(def->numatune)) {
d89b3e
+        if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
d89b3e
+              virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE))) {
d89b3e
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
d89b3e
+                           _("Per-node memory binding is not supported "
d89b3e
+                             "with this QEMU"));
d89b3e
+            goto cleanup;
d89b3e
+        }
d89b3e
+        useNodemask = true;
d89b3e
     }
d89b3e
 
d89b3e
-    if (def->mem.nhugepages && def->mem.hugepages[0].size &&
d89b3e
-        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
d89b3e
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
d89b3e
-                       _("huge pages per NUMA node are not "
d89b3e
-                         "supported with this QEMU"));
d89b3e
-        goto cleanup;
d89b3e
+    if (def->mem.nhugepages && def->mem.hugepages[0].size) {
d89b3e
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
d89b3e
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
d89b3e
+                           _("huge pages per NUMA node are not "
d89b3e
+                             "supported with this QEMU"));
d89b3e
+            goto cleanup;
d89b3e
+        }
d89b3e
+        useNodemask = true;
d89b3e
     }
d89b3e
 
d89b3e
     for (i = 0; i < def->mem.nhugepages; i++) {
d89b3e
@@ -6714,7 +6719,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
d89b3e
                 virBufferAsprintf(&buf, ",policy=%s", policy);
d89b3e
             }
d89b3e
 
d89b3e
-            if (hugepage || nodemask) {
d89b3e
+            if (useNodemask) {
d89b3e
                 virCommandAddArg(cmd, "-object");
d89b3e
                 virCommandAddArgBuffer(cmd, &buf;;
d89b3e
             } else {
d89b3e
@@ -6739,7 +6744,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
d89b3e
             virBufferAdd(&buf, tmpmask, -1);
d89b3e
         }
d89b3e
 
d89b3e
-        if (hugepage || nodemask)
d89b3e
+        if (useNodemask)
d89b3e
             virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
d89b3e
         else
d89b3e
             virBufferAsprintf(&buf, ",mem=%d", cellmem);
d89b3e
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args
d89b3e
new file mode 100644
d89b3e
index 0000000..481f72f
d89b3e
--- /dev/null
d89b3e
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args
d89b3e
@@ -0,0 +1,5 @@
d89b3e
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
d89b3e
+/usr/bin/qemu-system-x86_64 -S -M pc-q35-2.3 -m 128 \
d89b3e
+-smp 2,maxcpus=6,sockets=6,cores=1,threads=1 \
d89b3e
+-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi \
d89b3e
+-boot c -net none -serial none -parallel none
d89b3e
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml
d89b3e
new file mode 100644
d89b3e
index 0000000..01bbb3d
d89b3e
--- /dev/null
d89b3e
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml
d89b3e
@@ -0,0 +1,37 @@
d89b3e
+<domain type='kvm'>
d89b3e
+  <name>dummy2</name>
d89b3e
+  <uuid>4d92ec27-9ebf-400b-ae91-20c71c647c19</uuid>
d89b3e
+  <memory unit='KiB'>131072</memory>
d89b3e
+  <currentMemory unit='KiB'>65536</currentMemory>
d89b3e
+  <vcpu placement='auto' current='2'>6</vcpu>
d89b3e
+  <iothreads>2</iothreads>
d89b3e
+  <cputune>
d89b3e
+    <emulatorpin cpuset='1-3'/>
d89b3e
+    <iothreadpin iothread='1' cpuset='2'/>
d89b3e
+  </cputune>
d89b3e
+  <numatune>
d89b3e
+    <memory mode='strict' placement='auto'/>
d89b3e
+  </numatune>
d89b3e
+  <os>
d89b3e
+    <type arch='x86_64' machine='pc-q35-2.3'>hvm</type>
d89b3e
+    <boot dev='hd'/>
d89b3e
+  </os>
d89b3e
+  <clock offset='utc'/>
d89b3e
+  <on_poweroff>destroy</on_poweroff>
d89b3e
+  <on_reboot>restart</on_reboot>
d89b3e
+  <on_crash>destroy</on_crash>
d89b3e
+  <devices>
d89b3e
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
d89b3e
+    <controller type='sata' index='0'>
d89b3e
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
d89b3e
+    </controller>
d89b3e
+    <controller type='pci' index='0' model='pcie-root'/>
d89b3e
+    <controller type='pci' index='1' model='dmi-to-pci-bridge'>
d89b3e
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
d89b3e
+    </controller>
d89b3e
+    <controller type='pci' index='2' model='pci-bridge'>
d89b3e
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x01' function='0x0'/>
d89b3e
+    </controller>
d89b3e
+    <memballoon model='none'/>
d89b3e
+  </devices>
d89b3e
+</domain>
d89b3e
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args
d89b3e
index f81947e..27b3f8e 100644
d89b3e
--- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args
d89b3e
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args
d89b3e
@@ -1,6 +1,7 @@
d89b3e
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
d89b3e
 /usr/bin/qemu -S -M pc -m 1024 -smp 2 \
d89b3e
--numa node,nodeid=0,cpus=0,mem=256 \
d89b3e
+-object memory-backend-ram,size=256M,id=ram-node0 \
d89b3e
+-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
d89b3e
 -object memory-backend-file,prealloc=yes,\
d89b3e
 mem-path=/dev/hugepages1G/libvirt/qemu,size=768M,id=ram-node1 \
d89b3e
 -numa node,nodeid=1,cpus=1,memdev=ram-node1 \
d89b3e
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args b/tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args
d89b3e
new file mode 100644
d89b3e
index 0000000..0b1b0f5
d89b3e
--- /dev/null
d89b3e
+++ b/tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args
d89b3e
@@ -0,0 +1,5 @@
d89b3e
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
d89b3e
+/usr/bin/kvm -S -M pc -m 64 -smp 1 \
d89b3e
+-numa node,nodeid=0,cpus=0,mem=64 \
d89b3e
+-nographic -monitor unix:/tmp/test-monitor,server,nowait \
d89b3e
+-no-acpi -boot c -usb -net none -serial none -parallel none
d89b3e
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.args b/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.args
d89b3e
index 2addf97..b0e274c 100644
d89b3e
--- a/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.args
d89b3e
+++ b/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.args
d89b3e
@@ -2,6 +2,7 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
d89b3e
 /usr/bin/kvm -S -M pc -m 64 -smp 2 \
d89b3e
 -object memory-backend-ram,size=32M,id=ram-node0,host-nodes=3,policy=preferred \
d89b3e
 -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
d89b3e
--numa node,nodeid=1,cpus=1,mem=32 \
d89b3e
+-object memory-backend-ram,size=32M,id=ram-node1 \
d89b3e
+-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
d89b3e
 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
d89b3e
 -no-acpi -boot c -usb -net none -serial none -parallel none
d89b3e
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
d89b3e
index 98bb9ad..ee7397a 100644
d89b3e
--- a/tests/qemuxml2argvtest.c
d89b3e
+++ b/tests/qemuxml2argvtest.c
d89b3e
@@ -1246,6 +1246,10 @@ mymain(void)
d89b3e
     DO_TEST("blkiotune-device", QEMU_CAPS_NAME);
d89b3e
     DO_TEST("cputune", QEMU_CAPS_NAME);
d89b3e
     DO_TEST("cputune-zero-shares", QEMU_CAPS_NAME);
d89b3e
+    DO_TEST("cputune-numatune", QEMU_CAPS_SMP_TOPOLOGY,
d89b3e
+            QEMU_CAPS_KVM,
d89b3e
+            QEMU_CAPS_OBJECT_MEMORY_RAM,
d89b3e
+            QEMU_CAPS_OBJECT_MEMORY_FILE);
d89b3e
 
d89b3e
     DO_TEST("numatune-memory", NONE);
d89b3e
     DO_TEST_PARSE_ERROR("numatune-memory-invalid-nodeset", NONE);
d89b3e
@@ -1256,6 +1260,8 @@ mymain(void)
d89b3e
     DO_TEST_FAILURE("numatune-memnode-no-memory", NONE);
d89b3e
 
d89b3e
     DO_TEST("numatune-auto-nodeset-invalid", NONE);
d89b3e
+    DO_TEST("numatune-auto-prefer", QEMU_CAPS_OBJECT_MEMORY_RAM,
d89b3e
+            QEMU_CAPS_OBJECT_MEMORY_FILE);
d89b3e
     DO_TEST_PARSE_ERROR("numatune-memnode-nocpu", NONE);
d89b3e
     DO_TEST_PARSE_ERROR("numatune-memnodes-problematic", NONE);
d89b3e
     DO_TEST("numad", NONE);
d89b3e
-- 
d89b3e
2.3.0
d89b3e