[libvirt] [PATCH v2 1/2] add nodeset='all' for interleave mode

Peng Hao peng.hao2 at zte.com.cn
Sat Sep 29 10:58:01 UTC 2018


sometimes we hoped that the memory of vm can be evenly distributed in
all nodes according to interleave mode. But different hosts
has different node number. So we add nodeset='all' for interleave mode.

Signed-off-by: Peng Hao <peng.hao2 at zte.com.cn>
---
 src/conf/numa_conf.c          | 77 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
index 97a3ca4..a336a62 100644
--- a/src/conf/numa_conf.c
+++ b/src/conf/numa_conf.c
@@ -29,6 +29,9 @@
 #include "virnuma.h"
 #include "virstring.h"
 
+#if WITH_NUMACTL
+#include <numa.h>
+#endif
 /*
  * Distance definitions defined Conform ACPI 2.0 SLIT.
  * See include/linux/topology.h
@@ -66,6 +69,7 @@ typedef virDomainNumaNode *virDomainNumaNodePtr;
 struct _virDomainNuma {
     struct {
         bool specified;
+        bool allnode;
         virBitmapPtr nodeset;
         virDomainNumatuneMemMode mode;
         virDomainNumatunePlacement placement;
@@ -259,13 +263,21 @@ virDomainNumatuneParseXML(virDomainNumaPtr numa,
 
         tmp = virXMLPropString(node, "nodeset");
         if (tmp) {
-            if (virBitmapParse(tmp, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
-                goto cleanup;
-
-            if (virBitmapIsAllClear(nodeset)) {
+            if (STREQ(tmp, "all") && !virNumaIsAvailable()) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("Invalid value of 'nodeset': %s"), tmp);
+                              _("Invalid nodeset=%s when numactl is not supported"), tmp);
                 goto cleanup;
+            } else if (STREQ(tmp, "all") && virNumaIsAvailable()) {
+                numa->memory.allnode = true;
+            } else {
+                if (virBitmapParse(tmp, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
+                    goto cleanup;
+
+                if (virBitmapIsAllClear(nodeset)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("Invalid value of 'nodeset': %s"), tmp);
+                    goto cleanup;
+                }
             }
 
             VIR_FREE(tmp);
@@ -319,10 +331,14 @@ virDomainNumatuneFormatXML(virBufferPtr buf,
         virBufferAsprintf(buf, "<memory mode='%s' ", tmp);
 
         if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
-            if (!(nodeset = virBitmapFormat(numatune->memory.nodeset)))
-                return -1;
-            virBufferAsprintf(buf, "nodeset='%s'/>\n", nodeset);
-            VIR_FREE(nodeset);
+            if (numatune->memory.allnode == true) {
+                virBufferAddLit(buf, "nodeset='all'/>\n");
+            } else {
+                if (!(nodeset = virBitmapFormat(numatune->memory.nodeset)))
+                    return -1;
+                virBufferAsprintf(buf, "nodeset='%s'/>\n", nodeset);
+                VIR_FREE(nodeset);
+            }
         } else if (numatune->memory.placement) {
             tmp = virDomainNumatunePlacementTypeToString(numatune->memory.placement);
             virBufferAsprintf(buf, "placement='%s'/>\n", tmp);
@@ -489,6 +505,37 @@ virDomainNumatuneMaybeFormatNodeset(virDomainNumaPtr numatune,
     return 0;
 }
 
+#if WITH_NUMACTL
+static int
+makeAllnodeBitmap(virDomainNumaPtr numa)
+{
+    size_t i = 0, maxnode = 0;
+    virBitmapPtr bitmap = NULL;
+
+    if ((bitmap = virBitmapNew(VIR_DOMAIN_CPUMASK_LEN)) == NULL)
+        return -1;
+    virBitmapClearAll(bitmap);
+    maxnode = numa_max_node();
+    for (i = 0; i <= maxnode; i++) {
+        if (virBitmapSetBit(bitmap, i) < 0) {
+            virBitmapFree(bitmap);
+                return -1;
+        }
+    }
+
+    virBitmapFree(numa->memory.nodeset);
+    numa->memory.nodeset = bitmap;
+
+    return 0;
+}
+#else
+static int
+makeAllnodeBitmap(virDomainNumaPtr numa)
+{
+    return -1;
+}
+#endif
+
 int
 virDomainNumatuneSet(virDomainNumaPtr numa,
                      bool placement_static,
@@ -538,20 +585,28 @@ virDomainNumatuneSet(virDomainNumaPtr numa,
     }
 
     if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT) {
-        if (numa->memory.nodeset || placement_static)
+        if (numa->memory.nodeset || placement_static || numa->memory.allnode)
             placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
         else
             placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
     }
 
     if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC &&
-        !numa->memory.nodeset) {
+        !numa->memory.nodeset && !numa->memory.allnode) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("nodeset for NUMA memory tuning must be set "
                          "if 'placement' is 'static'"));
         goto cleanup;
     }
 
+    if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC &&
+        mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE &&
+        numa->memory.allnode && virNumaIsAvailable()) {
+
+        if (makeAllnodeBitmap(numa) < 0)
+            goto cleanup;
+    }
+
     /* setting nodeset when placement auto is invalid */
     if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
         numa->memory.nodeset) {
-- 
1.8.3.1




More information about the libvir-list mailing list