
On Thu, Jun 23, 2011 at 10:26:02PM -0600, Eric Blake wrote:
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 http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/