]> xenbits.xensource.com Git - libvirt.git/commitdiff
virnuma: Introduce virNumaNodeIsAvailable
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 16 Jun 2014 12:29:15 +0000 (14:29 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 19 Jun 2014 13:10:49 +0000 (15:10 +0200)
Not on all hosts the set of NUMA nodes IDs is continuous. This is
critical, because our code currently assumes the set doesn't contain
holes. For instance in nodeGetFreeMemory() we can see the following
pattern:

    if ((max_node = virNumaGetMaxNode()) < 0)
        return 0;

    for (n = 0; n <= max_node; n++) {
        ...
    }

while it should be something like this:

    if ((max_node = virNumaGetMaxNode()) < 0)
        return 0;

    for (n = 0; n <= max_node; n++) {
        if (!virNumaNodeIsAvailable(n))
            continue;
        ...
    }

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/libvirt_private.syms
src/util/virnuma.c
src/util/virnuma.h

index 9e25b8a17a455779e8436b25a5dd6d448e16686a..19a2d654f64b804eada66f34351da9682e200ff5 100644 (file)
@@ -1665,6 +1665,7 @@ virNumaGetDistances;
 virNumaGetMaxNode;
 virNumaGetNodeMemory;
 virNumaIsAvailable;
+virNumaNodeIsAvailable;
 virNumaSetupMemoryPolicy;
 virNumaTuneMemPlacementModeTypeFromString;
 virNumaTuneMemPlacementModeTypeToString;
index 1676208b2b761d6ca6e48b3176dc243e7c2f9879..5814cba7b06e6ee42c492721e90c20104cb58257 100644 (file)
@@ -406,6 +406,23 @@ virNumaGetMaxCPUs(void)
 
 
 #ifdef HAVE_NUMA_BITMASK_ISBITSET
+/**
+ * virNumaNodeIsAvailable:
+ * @node: node to check
+ *
+ * On some hosts the set of NUMA nodes isn't continuous.
+ * Use this function to test if the @node is available.
+ *
+ * Returns: true if @node is available,
+ *          false if @node doesn't exist
+ */
+bool
+virNumaNodeIsAvailable(int node)
+{
+    return numa_bitmask_isbitset(numa_nodes_ptr, node);
+}
+
+
 /**
  * virNumaGetDistances:
  * @node: identifier of the requested NUMA node
@@ -434,7 +451,7 @@ virNumaGetDistances(int node,
     int max_node;
     size_t i;
 
-    if (!numa_bitmask_isbitset(numa_nodes_ptr, node)) {
+    if (!virNumaNodeIsAvailable(node)) {
         VIR_DEBUG("Node %d does not exist", node);
         *distances = NULL;
         *ndistances = 0;
@@ -450,7 +467,7 @@ virNumaGetDistances(int node,
     *ndistances = max_node + 1;
 
     for (i = 0; i<= max_node; i++) {
-        if (!numa_bitmask_isbitset(numa_nodes_ptr, i))
+        if (!virNumaNodeIsAvailable(node))
             continue;
 
         (*distances)[i] = numa_distance(node, i);
@@ -460,7 +477,22 @@ virNumaGetDistances(int node,
  cleanup:
     return ret;
 }
+
+
 #else
+bool
+virNumaNodeIsAvailable(int node)
+{
+    int max_node = virNumaGetMaxNode();
+
+    if (max_node < 0)
+        return false;
+
+    /* Do we have anything better? */
+    return (node >= 0) && (node < max_node);
+}
+
+
 int
 virNumaGetDistances(int node ATTRIBUTE_UNUSED,
                     int **distances,
index fe1e9667cc32a98f7aa567e1203f1e008e852121..772296d8bd5bf252e99d74732ed96b3de54033f0 100644 (file)
@@ -58,6 +58,7 @@ int virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
 
 bool virNumaIsAvailable(void);
 int virNumaGetMaxNode(void);
+bool virNumaNodeIsAvailable(int node);
 int virNumaGetDistances(int node,
                         int **distances,
                         int *ndistances);