[libvirt] [PATCH 09/10] nodeinfo: Use a bitmap to keep track of node CPUs

Andrea Bolognani abologna at redhat.com
Fri Jul 17 16:13:28 UTC 2015


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




More information about the libvir-list mailing list