[PATCH v2 1/7] virnuma: Introduce virNumaNodeIsAvailable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 src/libvirt_private.syms |  1 +
 src/util/virnuma.c       | 36 ++++++++++++++++++++++++++++++++++--
 src/util/virnuma.h       |  1 +
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 122c572..946b264 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1663,6 +1663,7 @@ virNumaGetDistances;
 virNumaGetMaxNode;
 virNumaGetNodeMemory;
 virNumaIsAvailable;
+virNumaNodeIsAvailable;
 virNumaSetupMemoryPolicy;
 virNumaTuneMemPlacementModeTypeFromString;
 virNumaTuneMemPlacementModeTypeToString;
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 1676208..5814cba 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -407,6 +407,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
  * @distances: array of distances to sibling nodes
@@ -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,
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index fe1e966..772296d 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -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);
-- 
1.8.5.5

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]