From 05be6062822f3f694b9e2ba1982d60cad5c09f33 Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Mon, 20 Jul 2015 18:37:29 +0200 Subject: [PATCH] nodeinfo: Use a bitmap to keep track of node CPUs 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, 17 insertions(+), 9 deletions(-) diff --git a/src/nodeinfo.c b/src/nodeinfo.c index a9000f4ae5..764f3ea0e4 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -411,8 +411,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; @@ -437,6 +439,12 @@ virNodeParseNode(const char *sysfs_prefix, if (!online_cpus_map) goto cleanup; + npresent_cpus = virBitmapSize(present_cpumap); + + /* 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; @@ -448,6 +456,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; @@ -481,13 +493,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)) { @@ -530,9 +540,6 @@ virNodeParseNode(const char *sysfs_prefix, *threads = siblings; } - if (direrr < 0) - goto cleanup; - /* finalize the returned data */ *sockets = virBitmapCountBits(sockets_map); @@ -558,6 +565,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);