Avoid necessary checks for the numa library with this helper.
---
src/libvirt_private.syms | 1 +
src/nodeinfo.c | 37 ++++++++++++++++++++++---------------
src/util/virnuma.c | 37 +++++++++++++++++++++++++++++++++++++
src/util/virnuma.h | 2 ++
4 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 48d3da7..c8959ad 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1520,6 +1520,7 @@ virNodeSuspendGetTargetMask;
virDomainNumatuneMemModeTypeFromString;
virDomainNumatuneMemModeTypeToString;
virNumaGetAutoPlacementAdvice;
+virNumaGetMaxNode;
virNumaIsAvailable;
virNumaSetupMemoryPolicy;
virNumaTuneMemPlacementModeTypeFromString;
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index 8646a50..2a78778 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -966,25 +966,21 @@ int nodeGetMemoryStats(int cellNum ATTRIBUTE_UNUSED,
int ret;
char *meminfo_path = NULL;
FILE *meminfo;
+ int max_node;
if (cellNum == VIR_NODE_MEMORY_STATS_ALL_CELLS) {
if (VIR_STRDUP(meminfo_path, MEMINFO_PATH) < 0)
return -1;
} else {
- if (!virNumaIsAvailable()) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("NUMA not supported on this
host"));
+ if ((max_node = virNumaGetMaxNode()) < 0)
return -1;
- }
-# if WITH_NUMACTL
- if (cellNum > numa_max_node()) {
+ if (cellNum > max_node) {
virReportInvalidArg(cellNum,
_("cellNum in %s must be less than or equal to
%d"),
- __FUNCTION__, numa_max_node());
+ __FUNCTION__, max_node);
return -1;
}
-# endif
if (virAsprintf(&meminfo_path, "%s/node/node%d/meminfo",
SYSFS_SYSTEM_PATH, cellNum) < 0)
@@ -1595,7 +1591,9 @@ nodeGetCellMemory(int cell)
int maxCell;
/* Make sure the provided cell number is valid. */
- maxCell = numa_max_node();
+ if ((maxCell = virNumaGetMaxNode()) < 0)
+ return 0;
+
if (cell > maxCell) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cell %d out of range (0-%d)"),
@@ -1630,31 +1628,35 @@ nodeCapsInitNUMA(virCapsPtr caps)
virCapsHostNUMACellCPUPtr cpus = NULL;
int ret = -1;
int max_n_cpus = NUMA_MAX_N_CPUS;
+ int mask_n_bytes = max_n_cpus / 8;
int ncpus = 0;
bool topology_failed = false;
+ int max_node;
if (!virNumaIsAvailable())
return nodeCapsInitNUMAFake(caps);
- int mask_n_bytes = max_n_cpus / 8;
+ if ((max_node = virNumaGetMaxNode()) < 0)
+ goto cleanup;
+
if (VIR_ALLOC_N(mask, mask_n_bytes / sizeof(*mask)) < 0)
goto cleanup;
if (VIR_ALLOC_N(allonesmask, mask_n_bytes / sizeof(*mask)) < 0)
goto cleanup;
memset(allonesmask, 0xff, mask_n_bytes);
- for (n = 0; n <= numa_max_node(); n++) {
+ for (n = 0; n <= max_node; n++) {
size_t i;
/* The first time this returns -1, ENOENT if node doesn't exist... */
if (numa_node_to_cpus(n, mask, mask_n_bytes) < 0) {
VIR_WARN("NUMA topology for cell %d of %d not available,
ignoring",
- n, numa_max_node()+1);
+ n, max_node + 1);
continue;
}
/* second, third... times it returns an all-1's mask */
if (memcmp(mask, allonesmask, mask_n_bytes) == 0) {
VIR_DEBUG("NUMA topology for cell %d of %d is all ones, ignoring",
- n, numa_max_node()+1);
+ n, max_node + 1);
continue;
}
@@ -1709,7 +1711,9 @@ nodeGetCellsFreeMemory(unsigned long long *freeMems,
return nodeGetCellsFreeMemoryFake(freeMems,
startCell, maxCells);
- maxCell = numa_max_node();
+ if ((maxCell = virNumaGetMaxNode()) < 0)
+ return 0;
+
if (startCell > maxCell) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("start cell %d out of range (0-%d)"),
@@ -1737,13 +1741,16 @@ unsigned long long
nodeGetFreeMemory(void)
{
unsigned long long freeMem = 0;
+ int max_node;
int n;
if (!virNumaIsAvailable())
return nodeGetFreeMemoryFake();
+ if ((max_node = virNumaGetMaxNode()) < 0)
+ return 0;
- for (n = 0; n <= numa_max_node(); n++) {
+ for (n = 0; n <= max_node; n++) {
long long mem;
if (numa_node_size64(n, &mem) < 0)
continue;
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 11078a1..2d8d0e9 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -174,6 +174,34 @@ virNumaIsAvailable(void)
{
return numa_available() != -1;
}
+
+
+/**
+ * virNumaGetMaxNode:
+ * Get the highest node number available on the current system.
+ * (See the node numbers in /sys/devices/system/node/ ).
+ *
+ * Returns the highes NUMA node id on success, -1 on error.
+ */
+int
+virNumaGetMaxNode(void)
+{
+ int ret;
+
+ if (!virNumaIsAvailable()) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("NUMA isn't available on this host"));
+ return -1;
+ }
+
+ if ((ret = numa_max_node()) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to request maximum NUMA node id"));
+ return -1;
+ }
+
+ return ret;
+}
#else
int
virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
@@ -195,4 +223,13 @@ virNumaIsAvailable(void)
{
return false;
}
+
+
+int
+virNumaGetMaxNode(void)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("NUMA isn't available on this host"));
+ return -1;
+}
#endif
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index 5f9c38b..65636c3 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -57,4 +57,6 @@ int virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
virBitmapPtr nodemask);
bool virNumaIsAvailable(void);
+int virNumaGetMaxNode(void);
+
#endif /* __VIR_NUMA_H__ */
--
1.8.3.2