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

[libvirt] [PATCH v3 3/4] NUMA: cleanup for numa related codes



Intend to reduce the redundant code,use virNumaSetupMemoryPolicy
to replace virLXCControllerSetupNUMAPolicy and
qemuProcessInitNumaMemoryPolicy.

This patch also moves the numa related codes to the
file virnuma.c and virnuma.h

Signed-off-by: Gao feng <gaofeng cn fujitsu com>
---
 include/libvirt/libvirt.h.in |  15 ------
 src/conf/domain_conf.c       |  25 +++------
 src/conf/domain_conf.h       |  17 +-----
 src/libvirt_private.syms     |   9 ++--
 src/lxc/lxc_controller.c     | 114 +--------------------------------------
 src/qemu/qemu_cgroup.c       |   6 +--
 src/qemu/qemu_driver.c       |   2 +-
 src/qemu/qemu_process.c      | 121 +----------------------------------------
 src/util/virnuma.c           | 125 +++++++++++++++++++++++++++++++++++++++++++
 src/util/virnuma.h           |  45 ++++++++++++++++
 tools/virsh-domain.c         |   4 +-
 11 files changed, 192 insertions(+), 291 deletions(-)

diff --git PATCH v3include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index f6a7aff..b3bfd1d 100644
--- PATCH v3include/libvirt/libvirt.h.in	
+++ b/include/libvirt/libvirt.h.in
@@ -1762,21 +1762,6 @@ typedef enum {
 /* Manage numa parameters */
 
 /**
- * virDomainNumatuneMemMode:
- * Representation of the various modes in the <numatune> element of
- * a domain.
- */
-typedef enum {
-    VIR_DOMAIN_NUMATUNE_MEM_STRICT      = 0,
-    VIR_DOMAIN_NUMATUNE_MEM_PREFERRED   = 1,
-    VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE  = 2,
-
-#ifdef VIR_ENUM_SENTINELS
-    VIR_DOMAIN_NUMATUNE_MEM_LAST /* This constant is subject to change */
-#endif
-} virDomainNumatuneMemMode;
-
-/**
  * VIR_DOMAIN_NUMA_NODESET:
  *
  * Macro for typed parameter name that lists the numa nodeset of a
diff --git PATCH v3src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3278e9c..a256842 100644
--- PATCH v3src/conf/domain_conf.c	
+++ b/src/conf/domain_conf.c
@@ -690,11 +690,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
               "paravirt",
               "smpsafe");
 
-VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
-              "strict",
-              "preferred",
-              "interleave");
-
 VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST,
               "default",
               "mandatory",
@@ -709,12 +704,6 @@ VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST,
               "closed",
               "open");
 
-VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
-              VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
-              "default",
-              "static",
-              "auto");
-
 VIR_ENUM_IMPL(virDomainRNGModel,
               VIR_DOMAIN_RNG_MODEL_LAST,
               "virtio");
@@ -9822,7 +9811,7 @@ virDomainDefParseXML(virCapsPtr caps,
                     mode = virXMLPropString(cur, "mode");
                     if (mode) {
                         if ((def->numatune.memory.mode =
-                             virDomainNumatuneMemModeTypeFromString(mode)) < 0) {
+                             virNumatuneMemModeTypeFromString(mode)) < 0) {
                             virReportError(VIR_ERR_XML_ERROR,
                                            _("Unsupported NUMA memory "
                                              "tuning mode '%s'"),
@@ -9832,7 +9821,7 @@ virDomainDefParseXML(virCapsPtr caps,
                         }
                         VIR_FREE(mode);
                     } else {
-                        def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+                        def->numatune.memory.mode = VIR_NUMATUNE_MEM_STRICT;
                     }
 
                     nodeset = virXMLPropString(cur, "nodeset");
@@ -9851,7 +9840,7 @@ virDomainDefParseXML(virCapsPtr caps,
                     int placement_mode = 0;
                     if (placement) {
                         if ((placement_mode =
-                             virDomainNumatuneMemPlacementModeTypeFromString(placement)) < 0) {
+                             virNumatuneMemPlacementModeTypeFromString(placement)) < 0) {
                             virReportError(VIR_ERR_XML_ERROR,
                                            _("Unsupported memory placement "
                                              "mode '%s'"), placement);
@@ -9906,8 +9895,8 @@ virDomainDefParseXML(virCapsPtr caps,
          * and 'placement' of <vcpu> is 'auto'.
          */
         if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
-            def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
-            def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+            def->numatune.memory.placement_mode = VIR_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+            def->numatune.memory.mode = VIR_NUMATUNE_MEM_STRICT;
         }
     }
     VIR_FREE(nodes);
@@ -14812,7 +14801,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
         char *nodemask = NULL;
         const char *placement;
 
-        mode = virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode);
+        mode = virNumatuneMemModeTypeToString(def->numatune.memory.mode);
         virBufferAsprintf(buf, "    <memory mode='%s' ", mode);
 
         if (def->numatune.memory.placement_mode ==
@@ -14827,7 +14816,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
             virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
             VIR_FREE(nodemask);
         } else if (def->numatune.memory.placement_mode) {
-            placement = virDomainNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
+            placement = virNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
             virBufferAsprintf(buf, "placement='%s'/>\n", placement);
         }
         virBufferAddLit(buf, "  </numatune>\n");
diff --git PATCH v3src/conf/domain_conf.h b/src/conf/domain_conf.h
index 96f11ba..98c4745 100644
--- PATCH v3src/conf/domain_conf.h	
+++ b/src/conf/domain_conf.h
@@ -47,6 +47,7 @@
 # include "device_conf.h"
 # include "virbitmap.h"
 # include "virstoragefile.h"
+# include "virnuma.h"
 
 /* forward declarations of all device types, required by
  * virDomainDeviceDef
@@ -1700,18 +1701,6 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
                                                   int nvcpupin,
                                                   int vcpu);
 
-typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
-typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
-struct _virDomainNumatuneDef {
-    struct {
-        virBitmapPtr nodemask;
-        int mode;
-        int placement_mode; /* enum virDomainNumatuneMemPlacementMode */
-    } memory;
-
-    /* Future NUMA tuning related stuff should go here. */
-};
-
 typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
 typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
 struct _virBlkioDeviceWeight {
@@ -1801,7 +1790,7 @@ struct _virDomainDef {
         virDomainVcpuPinDefPtr emulatorpin;
     } cputune;
 
-    virDomainNumatuneDef numatune;
+    virNumatuneDef numatune;
 
     /* These 3 are based on virDomainLifeCycleAction enum flags */
     int onReboot;
@@ -2396,8 +2385,6 @@ VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
 VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
 VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
 VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
-VIR_ENUM_DECL(virDomainNumatuneMemMode)
-VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
 VIR_ENUM_DECL(virDomainHyperv)
 VIR_ENUM_DECL(virDomainRNGModel)
 VIR_ENUM_DECL(virDomainRNGBackend)
diff --git PATCH v3src/libvirt_private.syms b/src/libvirt_private.syms
index 1374470..9bf35a8 100644
--- PATCH v3src/libvirt_private.syms	
+++ b/src/libvirt_private.syms
@@ -252,10 +252,10 @@ virDomainNetRemove;
 virDomainNetTypeToString;
 virDomainNostateReasonTypeFromString;
 virDomainNostateReasonTypeToString;
-virDomainNumatuneMemModeTypeFromString;
-virDomainNumatuneMemModeTypeToString;
-virDomainNumatuneMemPlacementModeTypeFromString;
-virDomainNumatuneMemPlacementModeTypeToString;
+virNumatuneMemModeTypeFromString;
+virNumatuneMemModeTypeToString;
+virNumatuneMemPlacementModeTypeFromString;
+virNumatuneMemPlacementModeTypeToString;
 virDomainObjAssignDef;
 virDomainObjCopyPersistentDef;
 virDomainObjGetPersistentDef;
@@ -1547,6 +1547,7 @@ virNodeSuspendGetTargetMask;
 
 # util/virnuma.h
 virNumaGetAutoPlacementAdvice;
+virNumaSetupMemoryPolicy;
 
 # util/virobject.h
 virClassForObject;
diff --git PATCH v3src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index bb4cd16..6c5b8c8 100644
--- PATCH v3src/lxc/lxc_controller.c	
+++ b/src/lxc/lxc_controller.c
@@ -46,11 +46,6 @@
 # include <cap-ng.h>
 #endif
 
-#if WITH_NUMACTL
-# define NUMA_VERSION1_COMPATIBILITY 1
-# include <numa.h>
-#endif
-
 #include "virerror.h"
 #include "virlog.h"
 #include "virutil.h"
@@ -479,113 +474,6 @@ cleanup:
     return ret;
 }
 
-#if WITH_NUMACTL
-static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
-                                           virBitmapPtr nodemask)
-{
-    nodemask_t mask;
-    int mode = -1;
-    int node = -1;
-    int ret = -1;
-    int i = 0;
-    int maxnode = 0;
-    bool warned = false;
-    virDomainNumatuneDef numatune = ctrl->def->numatune;
-    virBitmapPtr tmp_nodemask = NULL;
-
-    if (numatune.memory.placement_mode ==
-        VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
-        if (!numatune.memory.nodemask)
-            return 0;
-        VIR_DEBUG("Set NUMA memory policy with specified nodeset");
-        tmp_nodemask = numatune.memory.nodemask;
-    } else if (numatune.memory.placement_mode ==
-               VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
-        VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
-        tmp_nodemask = nodemask;
-    } else {
-        return 0;
-    }
-
-    VIR_DEBUG("Setting NUMA memory policy");
-
-    if (numa_available() < 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       "%s", _("Host kernel is not aware of NUMA."));
-        return -1;
-    }
-
-    maxnode = numa_max_node() + 1;
-
-    /* Convert nodemask to NUMA bitmask. */
-    nodemask_zero(&mask);
-    i = -1;
-    while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
-        if (i > NUMA_NUM_NODES) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("Host cannot support NUMA node %d"), i);
-            return -1;
-        }
-        if (i > maxnode && !warned) {
-            VIR_WARN("nodeset is out of range, there is only %d NUMA "
-                     "nodes on host", maxnode);
-            warned = true;
-        }
-        nodemask_set(&mask, i);
-    }
-
-    mode = ctrl->def->numatune.memory.mode;
-
-    if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
-        numa_set_bind_policy(1);
-        numa_set_membind(&mask);
-        numa_set_bind_policy(0);
-    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
-        int nnodes = 0;
-        for (i = 0; i < NUMA_NUM_NODES; i++) {
-            if (nodemask_isset(&mask, i)) {
-                node = i;
-                nnodes++;
-            }
-        }
-
-        if (nnodes != 1) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           "%s", _("NUMA memory tuning in 'preferred' mode "
-                                   "only supports single node"));
-            goto cleanup;
-        }
-
-        numa_set_bind_policy(0);
-        numa_set_preferred(node);
-    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
-        numa_set_interleave_mask(&mask);
-    } else {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Unable to set NUMA policy %s"),
-                       virDomainNumatuneMemModeTypeToString(mode));
-        goto cleanup;
-    }
-
-    ret = 0;
-
-cleanup:
-    return ret;
-}
-#else
-static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
-                                           virBitmapPtr nodemask ATTRIBUTE_UNUSED)
-{
-    if (ctrl->def->numatune.memory.nodemask) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("NUMA policy is not available on this platform"));
-        return -1;
-    }
-
-    return 0;
-}
-#endif
-
 
 /*
  * To be run while still single threaded
@@ -684,7 +572,7 @@ static int virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl)
     int ret = -1;
 
     if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
-        virLXCControllerSetupNUMAPolicy(ctrl, nodemask) < 0)
+        virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
         goto cleanup;
 
     if (virLXCControllerSetupCpuAffinity(ctrl) < 0)
diff --git PATCH v3src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 9d6e88b..0a3dfc7 100644
--- PATCH v3src/qemu/qemu_cgroup.c	
+++ b/src/qemu/qemu_cgroup.c
@@ -423,12 +423,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
 
     if ((vm->def->numatune.memory.nodemask ||
          (vm->def->numatune.memory.placement_mode ==
-          VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
-        vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
+          VIR_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
+        vm->def->numatune.memory.mode == VIR_NUMATUNE_MEM_STRICT &&
         qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
         char *mask = NULL;
         if (vm->def->numatune.memory.placement_mode ==
-            VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+            VIR_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
             mask = virBitmapFormat(nodemask);
         else
             mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
diff --git PATCH v3src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9cd9e44..b4f0dcc 100644
--- PATCH v3src/qemu/qemu_driver.c	
+++ b/src/qemu/qemu_driver.c
@@ -7615,7 +7615,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
 
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 if (vm->def->numatune.memory.mode !=
-                    VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
+                    VIR_NUMATUNE_MEM_STRICT) {
                     virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                                    _("change of nodeset for running domain "
                                      "requires strict numa mode"));
diff --git PATCH v3src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 96ba70a..f12e54a 100644
--- PATCH v3src/qemu/qemu_process.c	
+++ b/src/qemu/qemu_process.c
@@ -45,11 +45,6 @@
 #include "qemu_bridge_filter.h"
 #include "qemu_migration.h"
 
-#if WITH_NUMACTL
-# define NUMA_VERSION1_COMPATIBILITY 1
-# include <numa.h>
-#endif
-
 #include "datatypes.h"
 #include "virlog.h"
 #include "virerror.h"
@@ -1791,120 +1786,6 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
 }
 
 
-/*
- * Set NUMA memory policy for qemu process, to be run between
- * fork/exec of QEMU only.
- */
-#if WITH_NUMACTL
-static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
-                                virBitmapPtr nodemask)
-{
-    nodemask_t mask;
-    int mode = -1;
-    int node = -1;
-    int ret = -1;
-    int i = 0;
-    int maxnode = 0;
-    bool warned = false;
-    virDomainNumatuneDef numatune = vm->def->numatune;
-    virBitmapPtr tmp_nodemask = NULL;
-
-    if (numatune.memory.placement_mode ==
-        VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
-        if (!numatune.memory.nodemask)
-            return 0;
-        VIR_DEBUG("Set NUMA memory policy with specified nodeset");
-        tmp_nodemask = numatune.memory.nodemask;
-    } else if (numatune.memory.placement_mode ==
-               VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
-        VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
-        tmp_nodemask = nodemask;
-    } else {
-        return 0;
-    }
-
-    if (numa_available() < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Host kernel is not aware of NUMA."));
-        return -1;
-    }
-
-    maxnode = numa_max_node() + 1;
-    /* Convert nodemask to NUMA bitmask. */
-    nodemask_zero(&mask);
-    i = -1;
-    while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
-        if (i > NUMA_NUM_NODES) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Host cannot support NUMA node %d"), i);
-            return -1;
-        }
-        if (i > maxnode && !warned) {
-            VIR_WARN("nodeset is out of range, there is only %d NUMA "
-                     "nodes on host", maxnode);
-            warned = true;
-        }
-        nodemask_set(&mask, i);
-    }
-
-    mode = numatune.memory.mode;
-
-    if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
-        numa_set_bind_policy(1);
-        numa_set_membind(&mask);
-        numa_set_bind_policy(0);
-    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
-        int nnodes = 0;
-        for (i = 0; i < NUMA_NUM_NODES; i++) {
-            if (nodemask_isset(&mask, i)) {
-                node = i;
-                nnodes++;
-            }
-        }
-
-        if (nnodes != 1) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           "%s", _("NUMA memory tuning in 'preferred' mode "
-                                   "only supports single node"));
-            goto cleanup;
-        }
-
-        numa_set_bind_policy(0);
-        numa_set_preferred(node);
-    } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
-        numa_set_interleave_mask(&mask);
-    } else {
-        /* XXX: Shouldn't go here, as we already do checking when
-         * parsing domain XML.
-         */
-        virReportError(VIR_ERR_XML_ERROR,
-                       "%s", _("Invalid mode for memory NUMA tuning."));
-        goto cleanup;
-    }
-
-    ret = 0;
-
-cleanup:
-    return ret;
-}
-#else
-static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
-                                virBitmapPtr nodemask ATTRIBUTE_UNUSED)
-{
-    if (vm->def->numatune.memory.nodemask) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("libvirt is compiled without NUMA tuning support"));
-
-        return -1;
-    }
-
-    return 0;
-}
-#endif
-
-
 /* Helper to prepare cpumap for affinity setting, convert
  * NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
  * just return a new allocated bitmap.
@@ -2654,7 +2535,7 @@ static int qemuProcessHook(void *data)
         qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
         goto cleanup;
 
-    if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
+    if (virNumaSetupMemoryPolicy(h->vm->def->numatune, h->nodemask) < 0)
         goto cleanup;
 
     ret = 0;
diff --git PATCH v3src/util/virnuma.c b/src/util/virnuma.c
index f6a6eb2..0601dcc 100644
--- PATCH v3src/util/virnuma.c	
+++ b/src/util/virnuma.c
@@ -21,12 +21,29 @@
 
 #include <config.h>
 
+#if WITH_NUMACTL
+# define NUMA_VERSION1_COMPATIBILITY 1
+# include <numa.h>
+#endif
+
 #include "virnuma.h"
 #include "vircommand.h"
 #include "virerror.h"
+#include "virlog.h"
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
+VIR_ENUM_IMPL(virNumatuneMemPlacementMode,
+              VIR_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
+              "default",
+              "static",
+              "auto");
+
+VIR_ENUM_IMPL(virNumatuneMemMode, VIR_NUMATUNE_MEM_LAST,
+              "strict",
+              "preferred",
+              "interleave");
+
 #if HAVE_NUMAD
 char *
 virNumaGetAutoPlacementAdvice(unsigned short vcpus,
@@ -59,3 +76,111 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus ATTRIBUTE_UNUSED,
     return NULL;
 }
 #endif
+
+#if WITH_NUMACTL
+int
+virNumaSetupMemoryPolicy(virNumatuneDef numatune,
+                         virBitmapPtr nodemask)
+{
+    nodemask_t mask;
+    int mode = -1;
+    int node = -1;
+    int ret = -1;
+    int i = 0;
+    int maxnode = 0;
+    bool warned = false;
+    virBitmapPtr tmp_nodemask = NULL;
+
+    if (numatune.memory.placement_mode ==
+        VIR_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
+        if (!numatune.memory.nodemask)
+            return 0;
+        VIR_DEBUG("Set NUMA memory policy with specified nodeset");
+        tmp_nodemask = numatune.memory.nodemask;
+    } else if (numatune.memory.placement_mode ==
+               VIR_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
+        VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
+        tmp_nodemask = nodemask;
+    } else {
+        return 0;
+    }
+
+    if (numa_available() < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Host kernel is not aware of NUMA."));
+        return -1;
+    }
+
+    maxnode = numa_max_node() + 1;
+    /* Convert nodemask to NUMA bitmask. */
+    nodemask_zero(&mask);
+    i = -1;
+    while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
+        if (i > NUMA_NUM_NODES) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Host cannot support NUMA node %d"), i);
+            return -1;
+        }
+        if (i > maxnode && !warned) {
+            VIR_WARN("nodeset is out of range, there is only %d NUMA "
+                     "nodes on host", maxnode);
+            warned = true;
+        }
+        nodemask_set(&mask, i);
+    }
+
+    mode = numatune.memory.mode;
+
+    if (mode == VIR_NUMATUNE_MEM_STRICT) {
+        numa_set_bind_policy(1);
+        numa_set_membind(&mask);
+        numa_set_bind_policy(0);
+    } else if (mode == VIR_NUMATUNE_MEM_PREFERRED) {
+        int nnodes = 0;
+        for (i = 0; i < NUMA_NUM_NODES; i++) {
+            if (nodemask_isset(&mask, i)) {
+                node = i;
+                nnodes++;
+            }
+        }
+
+        if (nnodes != 1) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "%s", _("NUMA memory tuning in 'preferred' mode "
+                                   "only supports single node"));
+            goto cleanup;
+        }
+
+        numa_set_bind_policy(0);
+        numa_set_preferred(node);
+    } else if (mode == VIR_NUMATUNE_MEM_INTERLEAVE) {
+        numa_set_interleave_mask(&mask);
+    } else {
+        /* XXX: Shouldn't go here, as we already do checking when
+         * parsing domain XML.
+         */
+        virReportError(VIR_ERR_XML_ERROR,
+                       "%s", _("Invalid mode for memory NUMA tuning."));
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    return ret;
+}
+#else
+int
+virNumaSetupMemoryPolicy(virNumatuneDef numatune,
+                         virBitmapPtr nodemask ATTRIBUTE_UNUSED)
+{
+    if (numatune.memory.nodemask) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("libvirt is compiled without NUMA tuning support"));
+
+        return -1;
+    }
+
+    return 0;
+}
+#endif
diff --git PATCH v3src/util/virnuma.h b/src/util/virnuma.h
index d3d7d3e..5fdf39e 100644
--- PATCH v3src/util/virnuma.h	
+++ b/src/util/virnuma.h
@@ -22,7 +22,52 @@
 #ifndef __VIR_NUMA_H__
 # define __VIR_NUMA_H__
 
+# include "internal.h"
+# include "virbitmap.h"
+# include "virutil.h"
+
+enum virNumatuneMemPlacementMode {
+    VIR_NUMATUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
+    VIR_NUMATUNE_MEM_PLACEMENT_MODE_STATIC,
+    VIR_NUMATUNE_MEM_PLACEMENT_MODE_AUTO,
+
+    VIR_NUMATUNE_MEM_PLACEMENT_MODE_LAST
+};
+
+VIR_ENUM_DECL(virNumatuneMemPlacementMode)
+
+/**
+ * virNumatuneMemMode:
+ * Representation of the various modes in the <numatune> element of
+ * a domain.
+ */
+typedef enum {
+    VIR_NUMATUNE_MEM_STRICT      = 0,
+    VIR_NUMATUNE_MEM_PREFERRED   = 1,
+    VIR_NUMATUNE_MEM_INTERLEAVE  = 2,
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_NUMATUNE_MEM_LAST /* This constant is subject to change */
+# endif
+} virNumatuneMemMode;
+
+VIR_ENUM_DECL(virNumatuneMemMode)
+
+typedef struct _virNumatuneDef virNumatuneDef;
+typedef virNumatuneDef *virNumatuneDefPtr;
+struct _virNumatuneDef {
+    struct {
+        virBitmapPtr nodemask;
+        int mode;
+        int placement_mode; /* enum virNumatuneMemPlacementMode */
+    } memory;
+
+    /* Future NUMA tuning related stuff should go here. */
+};
+
 char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
                                     unsigned long long balloon);
 
+int virNumaSetupMemoryPolicy(virNumatuneDef numatune,
+                             virBitmapPtr nodemask);
 #endif /* __VIR_NUMA_H__ */
diff --git PATCH v3tools/virsh-domain.c b/tools/virsh-domain.c
index e9da11f..0ff5ae6 100644
--- PATCH v3tools/virsh-domain.c	
+++ b/tools/virsh-domain.c
@@ -7473,7 +7473,7 @@ cmdNumatune(vshControl * ctl, const vshCmd * cmd)
         /* Accept string or integer, in case server understands newer
          * integer than what strings we were compiled with
          */
-        if ((m = virDomainNumatuneMemModeTypeFromString(mode)) < 0 &&
+        if ((m = virNumatuneMemModeTypeFromString(mode)) < 0 &&
             virStrToLong_i(mode, NULL, 0, &m) < 0) {
             vshError(ctl, _("Invalid mode: %s"), mode);
             goto cleanup;
@@ -7509,7 +7509,7 @@ cmdNumatune(vshControl * ctl, const vshCmd * cmd)
             if (params[i].type == VIR_TYPED_PARAM_INT &&
                 STREQ(params[i].field, VIR_DOMAIN_NUMA_MODE)) {
                 vshPrint(ctl, "%-15s: %s\n", params[i].field,
-                         virDomainNumatuneMemModeTypeToString(params[i].value.i));
+                         virNumatuneMemModeTypeToString(params[i].value.i));
             } else {
                 char *str = vshGetTypedParamValue(ctl, &params[i]);
                 vshPrint(ctl, "%-15s: %s\n", params[i].field, str);
-- 
1.7.11.7


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