Use NUMA's older nodemask_t (fixed-size map) rather than the
newer
'struct bitmask' (variable-size) in order to still compile on RHEL 5,
with its numactl-devel-0.9.8.
* src/qemu/qemu_process.c [HAVE_NUMA]: Prefer back-compat mode.
(qemuProcessInitNumaMemoryPolicy): Use older nodemask_t.
---
This fixes
https://www.redhat.com/archives/libvir-list/2011-June/msg01067.html
but it was big enough that I can't justify the build-breaker rule for
pushing it. Tested on RHEL 5 and Fedora 14. See also nodeinfo.c, where
we ask for back-compat.
src/qemu/qemu_process.c | 57 ++++++++++++++---------------------------------
1 files changed, 17 insertions(+), 40 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b4c732d..2f01788 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -40,6 +40,7 @@
#include "qemu_bridge_filter.h"
#if HAVE_NUMACTL
+# define NUMA_VERSION1_COMPATIBILITY 1
# include <numa.h>
#endif
@@ -1188,7 +1189,7 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver,
static int
qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
{
- struct bitmask *mask = NULL;
+ nodemask_t mask;
virErrorPtr orig_err = NULL;
virErrorPtr err = NULL;
int mode = -1;
@@ -1196,6 +1197,7 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
int ret = -1;
int i = 0;
int maxnode = 0;
+ bool warned = false;
if (!vm->def->numatune.memory.nodemask)
return 0;
@@ -1208,47 +1210,23 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
return -1;
}
- if (VIR_ALLOC(mask) < 0) {
- virReportOOMError();
- return -1;
- }
+ maxnode = numa_max_node() + 1;
- mask->size = VIR_DOMAIN_CPUMASK_LEN / sizeof (unsigned long);
- if (VIR_ALLOC_N(mask->maskp, mask->size) < 0) {
- virReportOOMError();
- goto cleanup;
- }
/* Convert nodemask to NUMA bitmask. */
+ nodemask_zero(&mask);
for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
- int cur = 0;
- int mod = 0;
-
- if (i) {
- cur = i / (8 * sizeof (unsigned long));
- mod = i % (8 * sizeof (unsigned long));
- }
-
if (vm->def->numatune.memory.nodemask[i]) {
- mask->maskp[cur] |= 1 << mod;
- }
- }
-
- maxnode = numa_max_node() + 1;
-
- for (i = 0; i < mask->size; i++) {
- if (i < (maxnode % (8 * sizeof (unsigned long)))) {
- if (mask->maskp[i] & ~maxnode) {
+ if (i > NUMA_NUM_NODES) {
+ qemuReportError(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);
- break;
+ warned = true;
}
-
- continue;
- }
-
- if (mask->maskp[i]) {
- VIR_WARN("nodeset is out of range, there is only %d NUMA nodes "
- "on host", maxnode);
+ nodemask_set(&mask, i);
}
}
@@ -1257,7 +1235,7 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
numa_set_bind_policy(1);
- numa_set_membind(mask);
+ numa_set_membind(&mask);
numa_set_bind_policy(0);
err = virGetLastError();
@@ -1271,8 +1249,8 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
}
} else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
int nnodes = 0;
- for (i = 0; i < mask->size; i++) {
- if (numa_bitmask_isbitset(mask, i)) {
+ for (i = 0; i < NUMA_NUM_NODES; i++) {
+ if (nodemask_isset(&mask, i)) {
node = i;
nnodes++;
}
@@ -1298,7 +1276,7 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
goto cleanup;
}
} else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
- numa_set_interleave_mask(mask);
+ numa_set_interleave_mask(&mask);
err = virGetLastError();
if ((err && (err->code != orig_err->code)) ||
@@ -1321,7 +1299,6 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
ret = 0;
cleanup:
- numa_bitmask_free(mask);
return ret;
}
#else
A bit hard to read, but ACK, looks fine to me :-)
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit