edecca
From cb0d627bf064a14c83f3d34e8b73d77ed1733843 Mon Sep 17 00:00:00 2001
edecca
Message-Id: <cb0d627bf064a14c83f3d34e8b73d77ed1733843@dist-git>
edecca
From: Pavel Hrdina <phrdina@redhat.com>
edecca
Date: Mon, 13 Aug 2018 19:21:54 +0200
edecca
Subject: [PATCH] conf: Introduce virDomainDefPostParseMemtune
edecca
MIME-Version: 1.0
edecca
Content-Type: text/plain; charset=UTF-8
edecca
Content-Transfer-Encoding: 8bit
edecca
edecca
Previously we were ignoring "nodeset" attribute for hugepage pages
edecca
if there was no guest NUMA topology configured in the domain XML.
edecca
Commit <fa6bdf6afa878b8d7c5ed71664ee72be8967cdc5> partially fixed
edecca
that issue but it introduced a somehow valid regression.
edecca
edecca
In case that there is no guest NUMA topology configured and the
edecca
"nodeset" attribute is set to "0" it was accepted and was working
edecca
properly even though it was not completely valid XML.
edecca
edecca
This patch introduces a workaround that it will ignore the nodeset="0"
edecca
only in case that there is no guest NUMA topology in order not to
edecca
hit the validation error.
edecca
edecca
After this commit the following XML configuration is valid:
edecca
edecca
  <memoryBacking>
edecca
    <hugepages>
edecca
      <page size='2048' unit='KiB' nodeset='0'/>
edecca
    </hugepages>
edecca
  </memoryBacking>
edecca
edecca
but this configuration remains invalid:
edecca
edecca
  <memoryBacking>
edecca
    <hugepages>
edecca
      <page size='2048' unit='KiB' nodeset='0'/>
edecca
      <page size='1048576' unit='KiB'/>
edecca
    </hugepages>
edecca
  </memoryBacking>
edecca
edecca
The issue with the second configuration is that it was originally
edecca
working, however changing the order of the <page> elements resolved
edecca
into using different page size for the guest.  The code is written
edecca
in a way that it expect only one page configured and always uses only
edecca
the first page in case that there is no guest NUMA topology configured.
edecca
See qemuBuildMemPathStr() function for details.
edecca
edecca
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1591235
edecca
edecca
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
edecca
(cherry picked from commit 0a476f152150f62306f9f8d124aa44e4adb9158c)
edecca
edecca
Conflicts:
edecca
    tests/qemuxml2argvdata/hugepages-nodeset.args
edecca
        - missing upstream commit <caccbba64a>
edecca
edecca
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1615461
edecca
edecca
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
edecca
Reviewed-by: Ján Tomko <jtomko@redhat.com>
edecca
---
edecca
 src/conf/domain_conf.c                        | 27 +++++++++++++++++
edecca
 tests/qemuxml2argvdata/hugepages-nodeset.args | 26 ++++++++++++++++
edecca
 tests/qemuxml2argvtest.c                      |  2 +-
edecca
 .../qemuxml2xmloutdata/hugepages-nodeset.xml  | 30 +++++++++++++++++++
edecca
 tests/qemuxml2xmltest.c                       |  1 +
edecca
 5 files changed, 85 insertions(+), 1 deletion(-)
edecca
 create mode 100644 tests/qemuxml2argvdata/hugepages-nodeset.args
edecca
 create mode 100644 tests/qemuxml2xmloutdata/hugepages-nodeset.xml
edecca
edecca
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
edecca
index 98e833c5bb..8a43e607e9 100644
edecca
--- a/src/conf/domain_conf.c
edecca
+++ b/src/conf/domain_conf.c
edecca
@@ -4088,6 +4088,31 @@ virDomainDefPostParseMemory(virDomainDefPtr def,
edecca
 }
edecca
 
edecca
 
edecca
+static void
edecca
+virDomainDefPostParseMemtune(virDomainDefPtr def)
edecca
+{
edecca
+    size_t i;
edecca
+
edecca
+    if (virDomainNumaGetNodeCount(def->numa) == 0) {
edecca
+        /* If guest NUMA is not configured and any hugepage page has nodemask
edecca
+         * set to "0" free and clear that nodemas, otherwise we would rise
edecca
+         * an error that there is no guest NUMA node configured. */
edecca
+        for (i = 0; i < def->mem.nhugepages; i++) {
edecca
+            ssize_t nextBit;
edecca
+
edecca
+            if (!def->mem.hugepages[i].nodemask)
edecca
+                continue;
edecca
+
edecca
+            nextBit = virBitmapNextSetBit(def->mem.hugepages[i].nodemask, 0);
edecca
+            if (nextBit < 0) {
edecca
+                virBitmapFree(def->mem.hugepages[i].nodemask);
edecca
+                def->mem.hugepages[i].nodemask = NULL;
edecca
+            }
edecca
+        }
edecca
+    }
edecca
+}
edecca
+
edecca
+
edecca
 static int
edecca
 virDomainDefAddConsoleCompat(virDomainDefPtr def)
edecca
 {
edecca
@@ -5155,6 +5180,8 @@ virDomainDefPostParseCommon(virDomainDefPtr def,
edecca
     if (virDomainDefPostParseMemory(def, data->parseFlags) < 0)
edecca
         return -1;
edecca
 
edecca
+    virDomainDefPostParseMemtune(def);
edecca
+
edecca
     if (virDomainDefRejectDuplicateControllers(def) < 0)
edecca
         return -1;
edecca
 
edecca
diff --git a/tests/qemuxml2argvdata/hugepages-nodeset.args b/tests/qemuxml2argvdata/hugepages-nodeset.args
edecca
new file mode 100644
edecca
index 0000000000..d094be1252
edecca
--- /dev/null
edecca
+++ b/tests/qemuxml2argvdata/hugepages-nodeset.args
edecca
@@ -0,0 +1,26 @@
edecca
+LC_ALL=C \
edecca
+PATH=/bin \
edecca
+HOME=/home/test \
edecca
+USER=test \
edecca
+LOGNAME=test \
edecca
+QEMU_AUDIO_DRV=none \
edecca
+/usr/bin/qemu-system-i686 \
edecca
+-name SomeDummyHugepagesGuest \
edecca
+-S \
edecca
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
edecca
+-m 1024 \
edecca
+-mem-prealloc \
edecca
+-mem-path /dev/hugepages2M/libvirt/qemu/-1-SomeDummyHugepagesGu \
edecca
+-smp 2,sockets=2,cores=1,threads=1 \
edecca
+-uuid ef1bdff4-27f3-4e85-a807-5fb4d58463cc \
edecca
+-display none \
edecca
+-no-user-config \
edecca
+-nodefaults \
edecca
+-chardev socket,id=charmonitor,\
edecca
+path=/tmp/lib/domain--1-SomeDummyHugepagesGu/monitor.sock,server,nowait \
edecca
+-mon chardev=charmonitor,id=monitor,mode=control \
edecca
+-rtc base=utc \
edecca
+-no-shutdown \
edecca
+-no-acpi \
edecca
+-boot c \
edecca
+-usb
edecca
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
edecca
index f82bca2637..e6c0120670 100644
edecca
--- a/tests/qemuxml2argvtest.c
edecca
+++ b/tests/qemuxml2argvtest.c
edecca
@@ -960,7 +960,7 @@ mymain(void)
edecca
     DO_TEST("hugepages-default-2M", NONE);
edecca
     DO_TEST("hugepages-default-system-size", NONE);
edecca
     DO_TEST_PARSE_ERROR("hugepages-default-1G-nodeset-2M", NONE);
edecca
-    DO_TEST_PARSE_ERROR("hugepages-nodeset", NONE);
edecca
+    DO_TEST("hugepages-nodeset", NONE);
edecca
     DO_TEST_PARSE_ERROR("hugepages-nodeset-nonexist",
edecca
                         QEMU_CAPS_DEVICE_PC_DIMM,
edecca
                         QEMU_CAPS_OBJECT_MEMORY_FILE,
edecca
diff --git a/tests/qemuxml2xmloutdata/hugepages-nodeset.xml b/tests/qemuxml2xmloutdata/hugepages-nodeset.xml
edecca
new file mode 100644
edecca
index 0000000000..ac219a7800
edecca
--- /dev/null
edecca
+++ b/tests/qemuxml2xmloutdata/hugepages-nodeset.xml
edecca
@@ -0,0 +1,30 @@
edecca
+<domain type='qemu'>
edecca
+  <name>SomeDummyHugepagesGuest</name>
edecca
+  <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
edecca
+  <memory unit='KiB'>1048576</memory>
edecca
+  <currentMemory unit='KiB'>1048576</currentMemory>
edecca
+  <memoryBacking>
edecca
+    <hugepages>
edecca
+      <page size='2048' unit='KiB'/>
edecca
+    </hugepages>
edecca
+  </memoryBacking>
edecca
+  <vcpu placement='static'>2</vcpu>
edecca
+  <os>
edecca
+    <type arch='i686' machine='pc'>hvm</type>
edecca
+    <boot dev='hd'/>
edecca
+  </os>
edecca
+  <clock offset='utc'/>
edecca
+  <on_poweroff>destroy</on_poweroff>
edecca
+  <on_reboot>restart</on_reboot>
edecca
+  <on_crash>destroy</on_crash>
edecca
+  <devices>
edecca
+    <emulator>/usr/bin/qemu-system-i686</emulator>
edecca
+    <controller type='usb' index='0'>
edecca
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
edecca
+    </controller>
edecca
+    <controller type='pci' index='0' model='pci-root'/>
edecca
+    <input type='mouse' bus='ps2'/>
edecca
+    <input type='keyboard' bus='ps2'/>
edecca
+    <memballoon model='none'/>
edecca
+  </devices>
edecca
+</domain>
edecca
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
edecca
index aa543e9e51..b76410b2c1 100644
edecca
--- a/tests/qemuxml2xmltest.c
edecca
+++ b/tests/qemuxml2xmltest.c
edecca
@@ -336,6 +336,7 @@ mymain(void)
edecca
     DO_TEST("hugepages-default", NONE);
edecca
     DO_TEST("hugepages-default-2M", NONE);
edecca
     DO_TEST("hugepages-default-system-size", NONE);
edecca
+    DO_TEST("hugepages-nodeset", NONE);
edecca
     DO_TEST("hugepages-numa-default-2M", NONE);
edecca
     DO_TEST("hugepages-numa-default-dimm", NONE);
edecca
     DO_TEST("hugepages-numa-nodeset", NONE);
edecca
-- 
edecca
2.18.0
edecca