[libvirt] [PATCH 2/1] build: fix NUMA build on RHEL 5

Eric Blake eblake at redhat.com
Fri Jun 24 04:26:02 UTC 2011


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
-- 
1.7.4.4




More information about the libvir-list mailing list