Some devices creates empty (= cpu-less) NUMA nodes to host
its memory. This results in topologies where the following
sanity rule does not apply as is:
nodes * sockets * cores * threads = total_cpus
As a result, a call to 'virsh nodeinfo' will return the default
value (1) to nodes, sockets and threads, while cores defaults
to the total_cpus value. For example, in a Power9 host that has
160 total cpus, 4 cpu-less NUMA nodes, 2 populated NUMA nodes,
1 socket per populated node, 20 cores per socket and 4 threads
per socket:
$ virsh nodeinfo
CPU model: ppc64le
CPU(s): 160
CPU frequency: 3783 MHz
CPU socket(s): 1
Core(s) per socket: 160
Thread(s) per core: 1
NUMA cell(s): 1
Memory size: 535981376 KiB
This patch adjusts virHostCPUGetInfoPopulateLinux to count the
cpu-less NUMA nodes and discard them in the sanity rule, changing
it to:
(nodes - empty_nodes) * sockets * cores * threads = total_cpus
And with this new rule, virsh nodeinfo will return the
appropriate info for those topologies, without changing the
behavior for any other scenario it was previously working.
This is the resulting output of nodeinfo after this patch in the
same Power9 host mentioned above:
$ virsh nodeinfo
CPU model: ppc64le
CPU(s): 160
CPU frequency: 3783 MHz
CPU socket(s): 1
Core(s) per socket: 20
Thread(s) per core: 4
NUMA cell(s): 6
Memory size: 535981376 KiB
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/util/virhostcpu.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 6514c3d765..4100cf0e8c 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -598,6 +598,7 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
virBitmapPtr online_cpus_map = NULL;
DIR *nodedir = NULL;
struct dirent *nodedirent = NULL;
+ int emptynodes = 0;
int nodecpus, nodecores, nodesockets, nodethreads, offline = 0;
int threads_per_subcore = 0;
unsigned int node;
@@ -686,6 +687,8 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
VIR_FREE(sysfs_cpudir);
*cpus += nodecpus;
+ if (nodecpus == 0)
+ emptynodes++;
if (nodesockets > *sockets)
*sockets = nodesockets;
@@ -747,7 +750,7 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
* the nodeinfo structure isn't designed to carry the full topology so
* we're going to lie about the detected topology to notify the user
* to check the host capabilities for the actual topology. */
- if ((*nodes *
+ if (((*nodes - emptynodes) *
*sockets *
*cores *
*threads) != (*cpus + offline)) {
--
2.20.1