From e67ccd3cf8415b78ce0b800de3e51cc28f9a2d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 18 Dec 2019 06:31:53 -0500 Subject: [PATCH] conf: fix populating of fake NUMA in multi-node hosts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the host OS doesn't have NUMA present, we fallback to populating fake NUMA info and the code thus assumes only a single NUMA node. Unfortunately we also fallback to fake NUMA if numactl-devel was not present, and in this case we can still have multiple NUMA nodes. In this case we create all CPUs, but only the CPUs in the first node have any data filled in, resulting in capabilities like: 15977572 With this new code we get something slightly less broken 15977572 15977572 The topology at least now reflects what 'virsh nodeinfo' reports. The main bug is that the CPU "id" values won't match what the Linux host actually uses. Reviewed-by: Michal Privoznik Signed-off-by: Daniel P. Berrangé --- src/conf/capabilities.c | 67 ++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index b89fa22d74..da54591c11 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -1596,7 +1596,7 @@ virCapabilitiesHostNUMAInitFake(virCapsHostNUMAPtr caps) virNodeInfo nodeinfo; virCapsHostNUMACellCPUPtr cpus; int ncpus; - int s, c, t; + int n, s, c, t; int id, cid; int onlinecpus G_GNUC_UNUSED; bool tmp; @@ -1605,47 +1605,52 @@ virCapabilitiesHostNUMAInitFake(virCapsHostNUMAPtr caps) return -1; ncpus = VIR_NODEINFO_MAXCPUS(nodeinfo); - onlinecpus = nodeinfo.cpus; - if (VIR_ALLOC_N(cpus, ncpus) < 0) - return -1; - id = cid = 0; - for (s = 0; s < nodeinfo.sockets; s++) { - for (c = 0; c < nodeinfo.cores; c++) { - for (t = 0; t < nodeinfo.threads; t++) { - if (virHostCPUGetOnline(id, &tmp) < 0) - goto error; - if (tmp) { - cpus[cid].id = id; - cpus[cid].socket_id = s; - cpus[cid].core_id = c; - if (!(cpus[cid].siblings = virBitmapNew(ncpus))) + id = 0; + for (n = 0; n < nodeinfo.nodes; n++) { + int nodecpus = nodeinfo.sockets * nodeinfo.cores * nodeinfo.threads; + cid = 0; + + if (VIR_ALLOC_N(cpus, nodecpus) < 0) + return -1; + + for (s = 0; s < nodeinfo.sockets; s++) { + for (c = 0; c < nodeinfo.cores; c++) { + g_autoptr(virBitmap) siblings = virBitmapNew(ncpus); + for (t = 0; t < nodeinfo.threads; t++) + ignore_value(virBitmapSetBit(siblings, id + t)); + + for (t = 0; t < nodeinfo.threads; t++) { + if (virHostCPUGetOnline(id, &tmp) < 0) goto error; - ignore_value(virBitmapSetBit(cpus[cid].siblings, id)); - cid++; + if (tmp) { + cpus[cid].id = id; + cpus[cid].socket_id = s; + cpus[cid].core_id = c; + if (!(cpus[cid].siblings = virBitmapNew(ncpus))) + goto error; + virBitmapCopy(cpus[cid].siblings, siblings); + cid++; + } + + id++; } - - id++; } } - } - virCapabilitiesHostNUMAAddCell(caps, 0, - nodeinfo.memory, -#ifdef __linux__ - onlinecpus, cpus, -#else - ncpus, cpus, -#endif - 0, NULL, - 0, NULL); + virCapabilitiesHostNUMAAddCell(caps, 0, + nodeinfo.memory, + cid, cpus, + 0, NULL, + 0, NULL); + } return 0; error: - for (; id >= 0; id--) - virBitmapFree(cpus[id].siblings); + for (; cid >= 0; cid--) + virBitmapFree(cpus[cid].siblings); VIR_FREE(cpus); return -1; } -- GitLab