]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix handling of sparse NUMA topologies
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 17 Aug 2010 15:09:28 +0000 (11:09 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 24 Aug 2010 13:19:21 +0000 (14:19 +0100)
When finding a sparse NUMA topology, libnuma will return ENOENT
the first time it is invoked. On subsequent invocations it
will return success, but with an all-1's CPU mask. Check for
this, to avoid polluting the capabilities XML with 4096 bogus
CPUs

* src/nodeinfo.c: Check for all-1s CPU mask

src/nodeinfo.c

index 57db085d4821148871fad775ea4f2bec25e0cb53..65eeb245155115adb9854707d5fff842e6cd6e34 100644 (file)
@@ -361,6 +361,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
 {
     int n;
     unsigned long *mask = NULL;
+    unsigned long *allonesmask = NULL;
     int *cpus = NULL;
     int ret = -1;
     int max_n_cpus = NUMA_MAX_N_CPUS;
@@ -371,13 +372,23 @@ nodeCapsInitNUMA(virCapsPtr caps)
     int mask_n_bytes = max_n_cpus / 8;
     if (VIR_ALLOC_N(mask, mask_n_bytes / sizeof *mask) < 0)
         goto cleanup;
+    if (VIR_ALLOC_N(allonesmask, mask_n_bytes / sizeof *mask) < 0)
+        goto cleanup;
+    memset(allonesmask, 0xff, mask_n_bytes);
 
     for (n = 0 ; n <= numa_max_node() ; n++) {
         int i;
         int ncpus;
+        /* The first time this returns -1, ENOENT if node doesn't exist... */
         if (numa_node_to_cpus(n, mask, mask_n_bytes) < 0) {
             VIR_WARN("NUMA topology for cell %d of %d not available, ignoring",
-                     n, numa_max_node());
+                     n, numa_max_node()+1);
+            continue;
+        }
+        /* second, third... times it returns an all-1's mask */
+        if (memcmp(mask, allonesmask, mask_n_bytes) == 0) {
+            VIR_DEBUG("NUMA topology for cell %d of %d is all ones, ignoring",
+                      n, numa_max_node()+1);
             continue;
         }
 
@@ -406,6 +417,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
 cleanup:
     VIR_FREE(cpus);
     VIR_FREE(mask);
+    VIR_FREE(allonesmask);
     return ret;
 }