[libvirt] [PATCH] conf/qemu: enforce NUMA nodes only for x86 memory hotplug

Nikunj A Dadhania nikunj at linux.vnet.ibm.com
Tue Aug 18 10:05:11 UTC 2015


libvirt enforces at least one NUMA node for memory hotplug support on
all architectures. While it might be required for some x86 guest,
PowerPC can hotplug memory on non-NUMA system.

The generic checks are replaced with arch specific check and xml
validation too does not enforce "node" for non-x86 arch.

CC: Peter Krempa <pkrempa at redhat.com>
Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
---
 src/conf/domain_conf.c  |  9 ++++++---
 src/qemu/qemu_command.c | 28 +++++++++++++++++-----------
 2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index fd0450f..4cb2d4a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12430,6 +12430,7 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node,
 
 static int
 virDomainMemoryTargetDefParseXML(xmlNodePtr node,
+                                 const virDomainDef *domDef,
                                  xmlXPathContextPtr ctxt,
                                  virDomainMemoryDefPtr def)
 {
@@ -12437,7 +12438,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
     xmlNodePtr save = ctxt->node;
     ctxt->node = node;
 
-    if (virXPathUInt("string(./node)", ctxt, &def->targetNode) < 0) {
+    if (virXPathUInt("string(./node)", ctxt, &def->targetNode) < 0 && ARCH_IS_X86(domDef->os.arch)) {
         virReportError(VIR_ERR_XML_ERROR, "%s",
                        _("invalid or missing value of memory device node"));
         goto cleanup;
@@ -12457,6 +12458,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
 
 static virDomainMemoryDefPtr
 virDomainMemoryDefParseXML(xmlNodePtr memdevNode,
+                           const virDomainDef *domDef,
                            xmlXPathContextPtr ctxt,
                            unsigned int flags)
 {
@@ -12495,7 +12497,7 @@ virDomainMemoryDefParseXML(xmlNodePtr memdevNode,
         goto error;
     }
 
-    if (virDomainMemoryTargetDefParseXML(node, ctxt, def) < 0)
+    if (virDomainMemoryTargetDefParseXML(node, domDef, ctxt, def) < 0)
         goto error;
 
     if (virDomainDeviceInfoParseXML(memdevNode, NULL, &def->info, flags) < 0)
@@ -12647,7 +12649,7 @@ virDomainDeviceDefParse(const char *xmlStr,
             goto error;
         break;
     case VIR_DOMAIN_DEVICE_MEMORY:
-        if (!(dev->data.memory = virDomainMemoryDefParseXML(node, ctxt, flags)))
+        if (!(dev->data.memory = virDomainMemoryDefParseXML(node, def, ctxt, flags)))
             goto error;
         break;
     case VIR_DOMAIN_DEVICE_NONE:
@@ -16328,6 +16330,7 @@ virDomainDefParseXML(xmlDocPtr xml,
 
     for (i = 0; i < n; i++) {
         virDomainMemoryDefPtr mem = virDomainMemoryDefParseXML(nodes[i],
+                                                               def,
                                                                ctxt,
                                                                flags);
         if (!mem)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ae03618..51160e7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4979,8 +4979,12 @@ qemuBuildMemoryBackendStr(unsigned long long size,
     *backendProps = NULL;
     *backendType = NULL;
 
-    /* memory devices could provide a invalid guest node */
-    if (guestNode >= virDomainNumaGetNodeCount(def->numa)) {
+    /* memory devices could provide a invalid guest node. Moreover,
+     * x86 guests needs at least one numa node to support memory
+     * hotplug
+     */
+    if ((virDomainNumaGetNodeCount(def->numa) == 0 && ARCH_IS_X86(def->os.arch)) ||
+        guestNode > virDomainNumaGetNodeCount(def->numa)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("can't add memory backend for guest node '%d' as "
                          "the guest has only '%zu' NUMA nodes configured"),
@@ -4991,10 +4995,12 @@ qemuBuildMemoryBackendStr(unsigned long long size,
     if (!(props = virJSONValueNewObject()))
         return -1;
 
-    memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, guestNode);
-    if (virDomainNumatuneGetMode(def->numa, guestNode, &mode) < 0 &&
-        virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
-        mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+    if (virDomainNumaGetNodeCount(def->numa)) {
+        memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, guestNode);
+        if (virDomainNumatuneGetMode(def->numa, guestNode, &mode) < 0 &&
+            virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
+            mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+    }
 
     if (pagesize == 0) {
         /* Find the huge page size we want to use */
@@ -9238,11 +9244,11 @@ qemuBuildCommandLine(virConnectPtr conn,
             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) {
+        /* x86 windows guest needs at least one numa node to be
+         * present. While its not possible to detect what guest os is
+         * running, enforce this limitation only to x86 architecture.
+         */
+        if (ARCH_IS_X86(def->os.arch) && virDomainNumaGetNodeCount(def->numa) == 0) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("At least one numa node has to be configured when "
                              "enabling memory hotplug"));
-- 
2.4.3




More information about the libvir-list mailing list