[Bug 1957126] Re: lscpu not showing number of sockets on arm64
Gianfranco Costamagna
1957126 at bugs.launchpad.net
Wed Feb 5 07:23:02 UTC 2025
For some reasons I presume this was fixed in util-linux 2.40.2-14ubuntu1
merge
diff -Nru util-linux-2.40.2/debian/patches/upstream-master/lscpu-fix-incorrect-number-of-sockets-during-hotplug.patch util-linux-2.40.2/debian/patches/upstream-master/lscpu-fix-incorrect-number-of-sockets-during-hotplug.patch
--- util-linux-2.40.2/debian/patches/upstream-master/lscpu-fix-incorrect-number-of-sockets-during-hotplug.patch 1970-01-01 00:00:00.000000000 +0000
+++ util-linux-2.40.2/debian/patches/upstream-master/lscpu-fix-incorrect-number-of-sockets-during-hotplug.patch 2024-12-16 12:12:37.000000000 +0000
@@ -0,0 +1,201 @@
+From: Anjali K <anjalik at linux.ibm.com>
+Date: Mon, 4 Nov 2024 12:02:26 +0530
+Subject: lscpu: fix incorrect number of sockets during hotplug
+
+lscpu sometimes shows incorrect 'Socket(s)' value if a hotplug operation
+is running.
+On a 32 CPU 2-socket system, the expected output is as shown below:
+Architecture: ppc64le
+Byte Order: Little Endian
+CPU(s): 32
+On-line CPU(s) list: 0-31
+Model name: POWER10 (architected), altivec supported
+Model: 2.0 (pvr 0080 0200)
+Thread(s) per core: 8
+Core(s) per socket: 2
+Socket(s): 2
+
+On the same system, if hotplug is running along with lscpu, it shows
+"Socket(s):" as 3 and 4 incorrectly sometimes.
+Architecture: ppc64le
+Byte Order: Little Endian
+CPU(s): 32
+On-line CPU(s) list: 0-11,16-31
+Off-line CPU(s) list: 12-15
+Model name: POWER10 (architected), altivec supported
+Model: 2.0 (pvr 0080 0200)
+Thread(s) per core: 8
+Core(s) per socket: 1
+Socket(s): 3
+
+The number of sockets is considered as the number of unique core_siblings
+CPU groups. The issues causing the number of sockets to sometimes be
+higher during hotplug is:
+1. The core_siblings of CPUs on the same socket are different because a CPU
+on the socket has been onlined/offlined in between. In the below example,
+nr sockets was wrongly incremented for CPU 5 though CPU 4 and 5 are on the
+same socket because their core_siblings was different as CPU 12 was onlined
+in between.
+CPU: 4
+core_siblings: ff f0 0 0 0 0 0 0
+CPU: 5
+core_siblings: ff f8 0 0 0 0 0 0
+
+2. The core_siblings file of a CPU is created when a CPU is onlined. It may
+have an invalid value for some time until the online operation is fully
+complete. In the below example, nr sockets is wrongly incremented because
+the core_siblings of CPU 14 was 0 as it had just been onlined.
+CPU: 14
+core_siblings: 0 0 0 0 0 0 0 0
+
+To fix this, make the below changes:
+1. Instead of considering CPUs to be on different sockets if their
+core_siblings masks are unequal, consider them to be on different sockets
+only if their core_siblings masks don't have even one common CPU. Then CPUs
+on the same socket will be correctly identified even if offline/online
+operations happen while they are read if at least one CPU in the socket is
+online during both reads.
+2. Check if a CPU's hotplug operation has been completed before using its
+core_siblings file
+
+[kzak at redhat.com: - use xmalloc(),
+ - use ul_strtos32(),
+ - use err() on CPU_ALLOC() error]
+
+Reported-by: Anushree Mathur <anushree.mathur at linux.vnet.ibm.com>
+Signed-off-by: Anjali K <anjalik at linux.ibm.com>
+Signed-off-by: Karel Zak <kzak at redhat.com>
+---
+ sys-utils/lscpu-topology.c | 68 +++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 61 insertions(+), 7 deletions(-)
+
+diff --git a/sys-utils/lscpu-topology.c b/sys-utils/lscpu-topology.c
+index e3742e3..547a3ac 100644
+--- a/sys-utils/lscpu-topology.c
++++ b/sys-utils/lscpu-topology.c
+@@ -17,19 +17,25 @@
+ #include <unistd.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <ctype.h>
+
+ #include "lscpu.h"
+
+ /* add @set to the @ary, unnecessary set is deallocated. */
+-static int add_cpuset_to_array(cpu_set_t **ary, size_t *items, cpu_set_t *set, size_t setsize)
++static int add_cpuset_to_array(cpu_set_t **ary, size_t *items, cpu_set_t *set, size_t setsize, cpu_set_t *common_cpus_set)
+ {
+ size_t i;
+
+ if (!ary)
+ return -EINVAL;
+
++ /*
++ * Check if @set has no cpu in common with the cpusets
++ * saved in @ary and if so append @set to @ary.
++ */
+ for (i = 0; i < *items; i++) {
+- if (CPU_EQUAL_S(setsize, set, ary[i]))
++ CPU_AND_S(setsize, common_cpus_set, set, ary[i]);
++ if (CPU_COUNT_S(setsize, common_cpus_set))
+ break;
+ }
+ if (i == *items) {
+@@ -98,14 +104,46 @@ void lscpu_sort_caches(struct lscpu_cache *caches, size_t n)
+ qsort(caches, n, sizeof(struct lscpu_cache), cmp_cache);
+ }
+
++/*
++ * Get the hotplug state number representing a completely online
++ * cpu from /sys/devices/system/cpu/hotplug/state
++ */
++static int get_online_state(struct path_cxt *sys)
++{
++ int hp_online_state_val = 0, page_size, rc;
++ char *buf, *strp;
++
++ hp_online_state_val = -1;
++
++ /* sysfs text files have size = page size */
++ page_size = getpagesize();
++
++ buf = (char *)xmalloc(page_size);
++ rc = ul_path_readf_buffer(sys, buf, page_size, "hotplug/states");
++ if (rc <= 0)
++ goto done;
++
++ strp = strstr(buf, ": online");
++ if (!strp)
++ goto done;
++
++ strp--; /* get digits before ': online' */
++ while (strp >= buf && isdigit(*strp))
++ strp--;
++ ul_strtos32(strp + 1, &hp_online_state_val, 10);
++done:
++ free(buf);
++ return hp_online_state_val;
++}
+
+ /* Read topology for specified type */
+ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
+ {
+ size_t i, npos;
+ struct path_cxt *sys;
+- int nthreads = 0, sw_topo = 0;
++ int nthreads = 0, sw_topo = 0, rc, hp_state, hp_online_state;
+ FILE *fd;
++ cpu_set_t *temp_set;
+
+ sys = cxt->syscpu; /* /sys/devices/system/cpu/ */
+ npos = cxt->npossibles; /* possible CPUs */
+@@ -113,6 +151,12 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
+ DBG(TYPE, ul_debugobj(ct, "reading %s/%s/%s topology",
+ ct->vendor ?: "", ct->model ?: "", ct->modelname ?:""));
+
++ hp_online_state = get_online_state(sys);
++
++ temp_set = CPU_ALLOC(cxt->maxcpus);
++ if (!temp_set)
++ err(EXIT_FAILURE, _("cpuset_alloc failed"));
++
+ for (i = 0; i < cxt->npossibles; i++) {
+ struct lscpu_cpu *cpu = cxt->cpus[i];
+ cpu_set_t *thread_siblings = NULL, *core_siblings = NULL;
+@@ -127,6 +171,15 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
+ "cpu%d/topology/thread_siblings", num) != 0)
+ continue;
+
++ /*
++ * Ignore cpus which are not fully online.
++ * If hp_online_state is negative/zero or rc is negative,
++ * online state could not be read correctly, skip this check.
++ */
++ rc = ul_path_readf_s32(sys, &hp_state, "cpu%d/hotplug/state", num);
++ if (hp_online_state > 0 && rc >= 0 && hp_state != hp_online_state)
++ continue;
++
+ /* read topology maps */
+ ul_path_readf_cpuset(sys, &thread_siblings, cxt->maxcpus,
+ "cpu%d/topology/thread_siblings", num);
+@@ -163,15 +216,16 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
+
+ /* add to topology maps */
+ if (thread_siblings)
+- add_cpuset_to_array(ct->coremaps, &ct->ncores, thread_siblings, cxt->setsize);
++ add_cpuset_to_array(ct->coremaps, &ct->ncores, thread_siblings, cxt->setsize, temp_set);
+ if (core_siblings)
+- add_cpuset_to_array(ct->socketmaps, &ct->nsockets, core_siblings, cxt->setsize);
++ add_cpuset_to_array(ct->socketmaps, &ct->nsockets, core_siblings, cxt->setsize, temp_set);
+ if (book_siblings)
+- add_cpuset_to_array(ct->bookmaps, &ct->nbooks, book_siblings, cxt->setsize);
++ add_cpuset_to_array(ct->bookmaps, &ct->nbooks, book_siblings, cxt->setsize, temp_set);
+ if (drawer_siblings)
+- add_cpuset_to_array(ct->drawermaps, &ct->ndrawers, drawer_siblings, cxt->setsize);
++ add_cpuset_to_array(ct->drawermaps, &ct->ndrawers, drawer_siblings, cxt->setsize, temp_set);
+
+ }
++ CPU_FREE(temp_set);
+
+ /* s390 detects its cpu topology via /proc/sysinfo, if present.
+ * Using simply the cpu topology masks in sysfs will not give
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to util-linux in Ubuntu.
https://bugs.launchpad.net/bugs/1957126
Title:
lscpu not showing number of sockets on arm64
Status in golang-github-shirou-gopsutil package in Ubuntu:
New
Status in util-linux package in Ubuntu:
Fix Released
Bug description:
When running `lscpu` on arm64, the number of sockets is not populated.
This is seen on both Raspberry Pi hardware and in the autopkgtest
environment. Example output:
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Vendor ID: ARM
Model name: Cortex-A72
Model: 3
Thread(s) per core: 1
Core(s) per cluster: 4
Socket(s): -
Cluster(s): 1
Stepping: r0p3
CPU max MHz: 1500.0000
CPU min MHz: 600.0000
BogoMIPS: 108.00
Flags: fp asimd evtstrm crc32 cpuid
Vulnerabilities:
Itlb multihit: Not affected
L1tf: Not affected
Mds: Not affected
Meltdown: Not affected
Spec store bypass: Vulnerable
Spectre v1: Mitigation; __user pointer sanitization
Spectre v2: Vulnerable
Srbds: Not affected
Tsx async abort: Not affected
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/golang-github-shirou-gopsutil/+bug/1957126/+subscriptions
More information about the foundations-bugs
mailing list