diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4c1f61cefcd36d70bb51c6d8b4824eb4ad35db6d..d73a9f51008ec9e46108a0a35b649d27810912e2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1652,6 +1652,7 @@ virNodeSuspendGetTargetMask; virDomainNumatuneMemModeTypeFromString; virDomainNumatuneMemModeTypeToString; virNumaGetAutoPlacementAdvice; +virNumaGetDistances; virNumaGetMaxNode; virNumaGetNodeMemory; virNumaIsAvailable; diff --git a/src/util/virnuma.c b/src/util/virnuma.c index 1e099eb403e4c3f4e496a6b51ede230bf9e6f23a..e8ceec85307259a74c2f59595da17fab5b3897b0 100644 --- a/src/util/virnuma.c +++ b/src/util/virnuma.c @@ -216,6 +216,61 @@ virNumaGetMaxNode(void) } +/** + * virNumaGetDistances: + * @node: identifier of the requested NUMA node + * @distances: array of distances to sibling nodes + * @ndistances: size of @distances + * + * Get array of distances to sibling nodes from @node. If a + * distances[x] equals to zero, the node x is not enabled or + * doesn't exist. As a special case, if @node itself refers to + * disabled or nonexistent NUMA node, then @distances and + * @ndistances are set to NULL and zero respectively. + * + * The distances are a bit of magic. For a local node the value + * is 10, for remote it's typically 20 meaning that time penalty + * for accessing a remote node is two time bigger than when + * accessing a local node. + * + * Returns 0 on success, -1 otherwise. + */ +int +virNumaGetDistances(int node, + int **distances, + int *ndistances) +{ + int ret = -1; + int max_node; + size_t i; + + if (!numa_bitmask_isbitset(numa_nodes_ptr, node)) { + VIR_DEBUG("Node %d does not exist", node); + *distances = NULL; + *ndistances = 0; + return 0; + } + + if ((max_node = virNumaGetMaxNode()) < 0) + goto cleanup; + + if (VIR_ALLOC_N(*distances, max_node) < 0) + goto cleanup; + + *ndistances = max_node + 1; + + for (i = 0; i<= max_node; i++) { + if (!numa_bitmask_isbitset(numa_nodes_ptr, i)) + continue; + + (*distances)[i] = numa_distance(node, i); + } + + ret = 0; + cleanup: + return ret; +} + /** * virNumaGetNodeMemory: * @node: identifier of the requested NUMA node diff --git a/src/util/virnuma.h b/src/util/virnuma.h index 8464b19538e109e3144b9c1355fc585cd3c841c9..fe1e9667cc32a98f7aa567e1203f1e008e852121 100644 --- a/src/util/virnuma.h +++ b/src/util/virnuma.h @@ -58,6 +58,9 @@ int virNumaSetupMemoryPolicy(virNumaTuneDef numatune, bool virNumaIsAvailable(void); int virNumaGetMaxNode(void); +int virNumaGetDistances(int node, + int **distances, + int *ndistances); int virNumaGetNodeMemory(int node, unsigned long long *memsize, unsigned long long *memfree);