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 <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2014-06-16 14:29:15 +02:00
parent f182da20b0
commit 356c6f389f
3 changed files with 36 additions and 2 deletions

View File

@ -1665,6 +1665,7 @@ virNumaGetDistances;
virNumaGetMaxNode;
virNumaGetNodeMemory;
virNumaIsAvailable;
virNumaNodeIsAvailable;
virNumaSetupMemoryPolicy;
virNumaTuneMemPlacementModeTypeFromString;
virNumaTuneMemPlacementModeTypeToString;

View 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,

View 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);