Keep track of what CPUs belong to the current node while walking
through the sysfs node entry, so we don't need to do it a second
time immediately afterwards.
This also allows us to loop through all CPUs that are part of a
node in guaranteed ascending order, which is something that is
required for some upcoming changes.
---
src/nodeinfo.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index eceecc6..503fcdd 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -410,8 +410,10 @@ virNodeParseNode(const char *sysfs_prefix,
struct dirent *cpudirent = NULL;
virBitmapPtr present_cpumap = NULL;
virBitmapPtr online_cpus_map = NULL;
+ virBitmapPtr node_cpus_map = NULL;
virBitmapPtr sockets_map = NULL;
virBitmapPtr *cores_maps = NULL;
+ int npresent_cpus;
int sock_max = 0;
int sock;
int core;
@@ -429,13 +431,17 @@ virNodeParseNode(const char *sysfs_prefix,
goto cleanup;
}
- present_cpumap = nodeGetPresentCPUBitmap(sysfs_prefix, NULL);
+ present_cpumap = nodeGetPresentCPUBitmap(sysfs_prefix, &npresent_cpus);
if (!present_cpumap)
goto cleanup;
online_cpus_map = nodeGetOnlineCPUBitmap(sysfs_prefix, NULL);
if (!online_cpus_map)
goto cleanup;
+ /* Keep track of the CPUs that belong to the current node */
+ if (!(node_cpus_map = virBitmapNew(npresent_cpus)))
+ goto cleanup;
+
/* enumerate sockets in the node */
if (!(sockets_map = virBitmapNew(ID_MAX + 1)))
goto cleanup;
@@ -447,6 +453,10 @@ virNodeParseNode(const char *sysfs_prefix,
if (!virBitmapIsBitSet(present_cpumap, cpu))
continue;
+ /* Mark this CPU as part of the current node */
+ if (virBitmapSetBit(node_cpus_map, cpu) < 0)
+ goto cleanup;
+
if (!virBitmapIsBitSet(online_cpus_map, cpu))
continue;
@@ -480,13 +490,11 @@ virNodeParseNode(const char *sysfs_prefix,
if (!(cores_maps[i] = virBitmapNew(ID_MAX + 1)))
goto cleanup;
- /* iterate over all CPU's in the node */
- rewinddir(cpudir);
- while ((direrr = virDirRead(cpudir, &cpudirent, node)) > 0) {
- if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
- continue;
+ /* Iterate over all CPUs in the node, in ascending order */
+ for (cpu = 0; cpu < npresent_cpus; cpu++) {
- if (!virBitmapIsBitSet(present_cpumap, cpu))
+ /* Skip CPUs that are not part of the current node */
+ if (!virBitmapIsBitSet(node_cpus_map, cpu))
continue;
if (!virBitmapIsBitSet(online_cpus_map, cpu)) {
@@ -529,9 +537,6 @@ virNodeParseNode(const char *sysfs_prefix,
*threads = siblings;
}
- if (direrr < 0)
- goto cleanup;
-
/* finalize the returned data */
*sockets = virBitmapCountBits(sockets_map);
@@ -557,6 +562,7 @@ virNodeParseNode(const char *sysfs_prefix,
virBitmapFree(cores_maps[i]);
VIR_FREE(cores_maps);
virBitmapFree(sockets_map);
+ virBitmapFree(node_cpus_map);
virBitmapFree(online_cpus_map);
virBitmapFree(present_cpumap);
--
2.4.3