From 356c6f389fcff5ca74b393a0d94f7542c1be9d81 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 16 Jun 2014 14:29:15 +0200 Subject: [PATCH] virnuma: Introduce virNumaNodeIsAvailable 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 --- 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 9e25b8a17a..19a2d654f6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1665,6 +1665,7 @@ virNumaGetDistances; virNumaGetMaxNode; virNumaGetNodeMemory; virNumaIsAvailable; +virNumaNodeIsAvailable; virNumaSetupMemoryPolicy; virNumaTuneMemPlacementModeTypeFromString; virNumaTuneMemPlacementModeTypeToString; diff --git a/src/util/virnuma.c b/src/util/virnuma.c index 1676208b2b..5814cba7b0 100644 --- a/src/util/virnuma.c +++ b/src/util/virnuma.c @@ -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, diff --git a/src/util/virnuma.h b/src/util/virnuma.h index fe1e9667cc..772296d8bd 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);