[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 3/5 v3] numatune: Support persistent XML for numatune



* src/conf/domain_conf.h: Introduce one new struct for representing
NUMA tuning related stuffs.

* src/conf/domain_conf.c: Parse and format numatune XML.
---
 src/conf/domain_conf.c   |   72 ++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |   22 ++++++++++++++
 src/libvirt_private.syms |    2 +
 3 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 02707dd..8d5e173 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -484,6 +484,11 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
               "paravirt",
               "smpsafe");
 
+VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
+              "strict",
+              "preferred",
+              "interleave");
+
 #define virDomainReportError(code, ...)                              \
     virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__,            \
                          __FUNCTION__, __LINE__, __VA_ARGS__)
@@ -5875,6 +5880,51 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
     }
     VIR_FREE(nodes);
 
+    /* Extract numatune if exists. */
+    if ((n = virXPathNodeSet("./numatune", ctxt, NULL)) < 0) {
+        virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                             "%s", _("cannot extract numatune nodes"));
+        goto error;
+    }
+
+    if (n) {
+        tmp = virXPathString("string(./numatune/memory/@nodeset)", ctxt);
+        if (tmp) {
+            char *set = tmp;
+            int nodemasklen = VIR_DOMAIN_CPUMASK_LEN;
+
+            if (VIR_ALLOC_N(def->numatune.memory.nodemask, nodemasklen) < 0) {
+                virReportOOMError();
+                goto error;
+            }
+
+            /* "nodeset" leads same syntax with "cpuset". */
+            if (virDomainCpuSetParse((const char **)&set,
+                                     0, def->numatune.memory.nodemask,
+                                     nodemasklen) < 0)
+               goto error;
+            VIR_FREE(tmp);
+        } else {
+            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                "%s", _("nodeset for NUMA memory tuning must be set"));
+            goto error;
+        }
+
+        tmp = virXPathString("string(./numatune/memory/@mode)", ctxt);
+        if (tmp) {
+            if ((def->numatune.memory.mode =
+                virDomainNumatuneMemModeTypeFromString(tmp)) < 0) {
+                virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                    _("Unsupported NUMA memory tuning mode '%s'"),
+                                    tmp);
+                goto error;
+            }
+            VIR_FREE(tmp);
+        } else {
+            def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+        }
+    }
+
     n = virXPathNodeSet("./features/*", ctxt, &nodes);
     if (n < 0)
         goto error;
@@ -9457,6 +9507,28 @@ char *virDomainDefFormat(virDomainDefPtr def,
     if (def->cputune.shares || def->cputune.vcpupin)
         virBufferAddLit(&buf, "  </cputune>\n");
 
+    if (def->numatune.memory.nodemask)
+        virBufferAddLit(&buf, "  <numatune>\n");
+
+    if (def->numatune.memory.nodemask) {
+        char *nodemask = NULL;
+        nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask,
+                                         VIR_DOMAIN_CPUMASK_LEN);
+        if (nodemask == NULL) {
+            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                 "%s", _("failed to format nodeset for NUMA memory tuning"));
+            goto cleanup;
+        }
+
+        virBufferAsprintf(&buf, "    <memory mode='%s' nodeset='%s'/>\n",
+                          virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode),
+                          nodemask);
+        VIR_FREE(nodemask);
+    }
+
+    if (def->numatune.memory.nodemask)
+        virBufferAddLit(&buf, "  </numatune>\n");
+
     if (def->sysinfo)
         virDomainSysinfoDefFormat(&buf, def->sysinfo);
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1f4bf1d..3c54e8b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1117,6 +1117,25 @@ virDomainVcpupinDefPtr virDomainVcpupinFindByVcpu(virDomainVcpupinDefPtr *def,
                                                   int nvcpupin,
                                                   int vcpu);
 
+enum virDomainNumatuneMemMode {
+    VIR_DOMAIN_NUMATUNE_MEM_STRICT,
+    VIR_DOMAIN_NUMATUNE_MEM_PREFERRED,
+    VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE,
+
+    VIR_DOMAIN_NUMATUNE_MEM_LAST
+};
+
+typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
+typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
+struct _virDomainNumatuneDef {
+    struct {
+        char *nodemask;
+        int mode;
+    } memory;
+
+    /* Future NUMA tuning related stuff should go here. */
+};
+
 /*
  * Guest VM main configuration
  *
@@ -1156,6 +1175,8 @@ struct _virDomainDef {
         virDomainVcpupinDefPtr *vcpupin;
     } cputune;
 
+    virDomainNumatuneDef numatune;
+
     /* These 3 are based on virDomainLifeCycleAction enum flags */
     int onReboot;
     int onPoweroff;
@@ -1564,6 +1585,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression)
 VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
 VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
 VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
+VIR_ENUM_DECL(virDomainNumatuneMemMode)
 /* from libvirt.h */
 VIR_ENUM_DECL(virDomainState)
 VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5202da3..ae18c0d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -310,6 +310,8 @@ virDomainNetIndexByMac;
 virDomainNetInsert;
 virDomainNetRemoveByMac;
 virDomainNetTypeToString;
+virDomainNumatuneMemModeTypeFromString;
+virDomainNumatuneMemModeTypeToString;
 virDomainObjAssignDef;
 virDomainObjCopyPersistentDef;
 virDomainObjGetPersistentDef;
-- 
1.7.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]