[libvirt] [PATCH v2 09/16] numatune: add support for per-node memory bindings in private APIs

Martin Kletzander mkletzan at redhat.com
Tue Jul 8 11:50:24 UTC 2014


Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 src/conf/numatune_conf.c | 111 ++++++++++++++++++++++++++++++++++++++++-------
 src/conf/numatune_conf.h |  14 ++++--
 src/libvirt_private.syms |   1 +
 src/lxc/lxc_cgroup.c     |   3 +-
 src/qemu/qemu_cgroup.c   |   2 +-
 src/qemu/qemu_driver.c   |  10 ++---
 src/util/virnuma.c       |   6 +--
 7 files changed, 117 insertions(+), 30 deletions(-)

diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index 67fc799..60b6867 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -63,6 +63,18 @@ struct _virDomainNumatune {
 };


+static inline bool
+numa_cell_specified(virDomainNumatunePtr numatune,
+                    int cellid)
+{
+    if (numatune &&
+        cellid >= 0 &&
+        cellid < numatune->nmem_nodes)
+        return numatune->mem_nodes[cellid].nodeset;
+
+    return false;
+}
+
 static int
 virDomainNumatuneNodeParseXML(virDomainDefPtr def,
                               xmlXPathContextPtr ctxt)
@@ -312,6 +324,7 @@ void
 virDomainNumatuneFree(virDomainNumatunePtr numatune)
 {
     size_t i = 0;
+
     if (!numatune)
         return;

@@ -324,26 +337,37 @@ virDomainNumatuneFree(virDomainNumatunePtr numatune)
 }

 virDomainNumatuneMemMode
-virDomainNumatuneGetMode(virDomainNumatunePtr numatune)
+virDomainNumatuneGetMode(virDomainNumatunePtr numatune,
+                         int cellid)
 {
-    return (numatune && numatune->memory.specified) ? numatune->memory.mode : 0;
+    if (!numatune)
+        return 0;
+
+    if (numa_cell_specified(numatune, cellid))
+        return numatune->mem_nodes[cellid].mode;
+
+    if (numatune->memory.specified)
+        return numatune->memory.mode;
+
+    return 0;
 }

 virBitmapPtr
 virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,
-                            virBitmapPtr auto_nodeset)
+                            virBitmapPtr auto_nodeset,
+                            int cellid)
 {
     if (!numatune)
         return NULL;

-    if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
+    if (numatune->memory.specified &&
+        numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
         return auto_nodeset;

-    /*
-     * This weird logic has the same meaning as switch with
-     * auto/static/default, but can be more readably changed later.
-     */
-    if (numatune->memory.placement != VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC)
+    if (numa_cell_specified(numatune, cellid))
+        return numatune->mem_nodes[cellid].nodeset;
+
+    if (!numatune->memory.specified)
         return NULL;

     return numatune->memory.nodeset;
@@ -351,23 +375,30 @@ virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,

 char *
 virDomainNumatuneFormatNodeset(virDomainNumatunePtr numatune,
-                               virBitmapPtr auto_nodeset)
+                               virBitmapPtr auto_nodeset,
+                               int cellid)
 {
     return virBitmapFormat(virDomainNumatuneGetNodeset(numatune,
-                                                       auto_nodeset));
+                                                       auto_nodeset,
+                                                       cellid));
 }

 int
 virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
                                     virBitmapPtr auto_nodeset,
-                                    char **mask)
+                                    char **mask,
+                                    int cellid)
 {
     *mask = NULL;

     if (!numatune)
         return 0;

-    if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
+    if (!numa_cell_specified(numatune, cellid) && !numatune->memory.specified)
+        return 0;
+
+    if (numatune->memory.specified &&
+        numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
         !auto_nodeset) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Advice from numad is needed in case of "
@@ -375,7 +406,7 @@ virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
         return -1;
     }

-    *mask = virDomainNumatuneFormatNodeset(numatune, auto_nodeset);
+    *mask = virDomainNumatuneFormatNodeset(numatune, auto_nodeset, cellid);
     if (!*mask)
         return -1;

@@ -469,6 +500,35 @@ virDomainNumatuneSet(virDomainDefPtr def,
     return ret;
 }

+static bool
+virDomainNumatuneNodesEqual(virDomainNumatunePtr n1,
+                            virDomainNumatunePtr n2)
+{
+    size_t i = 0;
+
+    if (n1->nmem_nodes != n2->nmem_nodes)
+        return false;
+
+    for (i = 0; i < n1->nmem_nodes; i++) {
+        virDomainNumatuneNodePtr nd1 = &n1->mem_nodes[i];
+        virDomainNumatuneNodePtr nd2 = &n2->mem_nodes[i];
+
+        if (!nd1->nodeset && !nd2->nodeset)
+            continue;
+
+        if (!nd1->nodeset || !nd2->nodeset)
+            return false;
+
+        if (nd1->mode != nd2->mode)
+            return false;
+
+        if (!virBitmapEqual(nd1->nodeset, nd2->nodeset))
+            return false;
+    }
+
+    return true;
+}
+
 bool
 virDomainNumatuneEquals(virDomainNumatunePtr n1,
                         virDomainNumatunePtr n2)
@@ -480,7 +540,7 @@ virDomainNumatuneEquals(virDomainNumatunePtr n1,
         return false;

     if (!n1->memory.specified && !n2->memory.specified)
-        return true;
+        return virDomainNumatuneNodesEqual(n1, n2);

     if (!n1->memory.specified || !n2->memory.specified)
         return false;
@@ -491,7 +551,10 @@ virDomainNumatuneEquals(virDomainNumatunePtr n1,
     if (n1->memory.placement != n2->memory.placement)
         return false;

-    return virBitmapEqual(n1->memory.nodeset, n2->memory.nodeset);
+    if (!virBitmapEqual(n1->memory.nodeset, n2->memory.nodeset))
+        return false;
+
+    return virDomainNumatuneNodesEqual(n1, n2);
 }

 bool
@@ -508,3 +571,19 @@ virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune)

     return false;
 }
+
+bool
+virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune)
+{
+    size_t i = 0;
+
+    if (!numatune)
+        return false;
+
+    for (i = 0; i < numatune->nmem_nodes; i++) {
+        if (numatune->mem_nodes[i].nodeset)
+            return true;
+    }
+
+    return false;
+}
diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h
index 888cff1..c86118f 100644
--- a/src/conf/numatune_conf.h
+++ b/src/conf/numatune_conf.h
@@ -69,20 +69,24 @@ int virDomainNumatuneFormatXML(virBufferPtr buf, virDomainNumatunePtr numatune)
 /*
  * Getters
  */
-virDomainNumatuneMemMode virDomainNumatuneGetMode(virDomainNumatunePtr numatune);
+virDomainNumatuneMemMode virDomainNumatuneGetMode(virDomainNumatunePtr numatune,
+                                                  int cellid);

 virBitmapPtr virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,
-                                         virBitmapPtr auto_nodeset);
+                                         virBitmapPtr auto_nodeset,
+                                         int cellid);

 /*
  * Formatters
  */
 char *virDomainNumatuneFormatNodeset(virDomainNumatunePtr numatune,
-                                     virBitmapPtr auto_nodeset);
+                                     virBitmapPtr auto_nodeset,
+                                     int cellid);

 int virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
                                         virBitmapPtr auto_nodeset,
-                                        char **mask);
+                                        char **mask,
+                                        int cellid);

 /*
  * Setters
@@ -99,4 +103,6 @@ bool virDomainNumatuneEquals(virDomainNumatunePtr n1,

 bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune);

+bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
+
 #endif /* __NUMATUNE_CONF_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fcf1012..6a285be 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -614,6 +614,7 @@ virDomainNumatuneFormatXML;
 virDomainNumatuneFree;
 virDomainNumatuneGetMode;
 virDomainNumatuneGetNodeset;
+virDomainNumatuneHasPerNodeBinding;
 virDomainNumatuneHasPlacementAuto;
 virDomainNumatuneMaybeFormatNodeset;
 virDomainNumatuneMemModeTypeFromString;
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 8093791..9c46e86 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -79,7 +79,8 @@ static int virLXCCgroupSetupCpusetTune(virDomainDefPtr def,
             goto cleanup;
     }

-    if (virDomainNumatuneMaybeFormatNodeset(def->numatune, nodemask, &mask) < 0)
+    if (virDomainNumatuneMaybeFormatNodeset(def->numatune, nodemask,
+                                            &mask, -1) < 0)
         goto cleanup;

     if (mask && virCgroupSetCpusetMems(cgroup, mask) < 0)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 3bae9b0..ff268fb 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -590,7 +590,7 @@ qemuSetupCpusetCgroup(virDomainObjPtr vm,

     if (virDomainNumatuneMaybeFormatNodeset(vm->def->numatune,
                                             nodemask,
-                                            &mem_mask) < 0)
+                                            &mem_mask, -1) < 0)
         goto cleanup;

     if (mem_mask &&
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 174fae8..5fbe863 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8636,7 +8636,7 @@ qemuDomainSetNumaParamsLive(virDomainObjPtr vm,
     size_t i = 0;
     int ret = -1;

-    if (virDomainNumatuneGetMode(vm->def->numatune) !=
+    if (virDomainNumatuneGetMode(vm->def->numatune, -1) !=
         VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("change of nodeset for running domain "
@@ -8777,7 +8777,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,

     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
         if (mode != -1 &&
-            virDomainNumatuneGetMode(vm->def->numatune) != mode) {
+            virDomainNumatuneGetMode(vm->def->numatune, -1) != mode) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("can't change numatune mode for running domain"));
             goto cleanup;
@@ -8873,15 +8873,15 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
                 goto cleanup;

             if (flags & VIR_DOMAIN_AFFECT_CONFIG)
-                param->value.i = virDomainNumatuneGetMode(persistentDef->numatune);
+                param->value.i = virDomainNumatuneGetMode(persistentDef->numatune, -1);
             else
-                param->value.i = virDomainNumatuneGetMode(vm->def->numatune);
+                param->value.i = virDomainNumatuneGetMode(vm->def->numatune, -1);
             break;

         case 1: /* fill numa nodeset here */
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
                 nodeset = virDomainNumatuneFormatNodeset(persistentDef->numatune,
-                                                         NULL);
+                                                         NULL, -1);
                 if (!nodeset)
                     goto cleanup;
             } else {
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 087f679..46f48d2 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -98,7 +98,7 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
     int maxnode = 0;
     virBitmapPtr tmp_nodemask = NULL;

-    tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask);
+    tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1);
     if (!tmp_nodemask)
         return 0;

@@ -123,7 +123,7 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
         nodemask_set(&mask, bit);
     }

-    switch (virDomainNumatuneGetMode(numatune)) {
+    switch (virDomainNumatuneGetMode(numatune, -1)) {
     case VIR_DOMAIN_NUMATUNE_MEM_STRICT:
         numa_set_bind_policy(1);
         numa_set_membind(&mask);
@@ -320,7 +320,7 @@ int
 virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
                          virBitmapPtr nodemask ATTRIBUTE_UNUSED)
 {
-    if (virDomainNumatuneGetNodeset(numatune, NULL)) {
+    if (virDomainNumatuneGetNodeset(numatune, NULL, -1)) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("libvirt is compiled without NUMA tuning support"));

-- 
2.0.0




More information about the libvir-list mailing list