Signed-off-by: Martin Kletzander <mkletzan(a)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