|
|
0e1b67 |
From 63d8d3e8d54326842677bc3d3a3e43a133846a71 Mon Sep 17 00:00:00 2001
|
|
|
0e1b67 |
From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
|
|
0e1b67 |
Date: Tue, 15 Dec 2020 12:07:38 +0100
|
|
|
0e1b67 |
Subject: [PATCH 51/55] lscpu: use cluster on aarch64 machine which doesn't
|
|
|
0e1b67 |
have ACPI PPTT
|
|
|
0e1b67 |
|
|
|
0e1b67 |
lscpu may show the wrong number of sockets if the machine is aarch64 and
|
|
|
0e1b67 |
doesn't have ACPI PPTT.
|
|
|
0e1b67 |
|
|
|
0e1b67 |
That's because lscpu show the number of sockets by using a sysfs entry
|
|
|
0e1b67 |
(cpu/cpuX/topology/core_siblings). The sysfs entry is set by MPIDR_EL1
|
|
|
0e1b67 |
register if the machine doesn't have ACPI PPTT. MPIDR_EL1 doesn't show
|
|
|
0e1b67 |
the physical socket information directly. It shows the affinity level.
|
|
|
0e1b67 |
|
|
|
0e1b67 |
According to linux/arch/arm64/kernel/topology.c:store_cpu_topology(),
|
|
|
0e1b67 |
the top level of affinity is called as 'Cluster'.
|
|
|
0e1b67 |
|
|
|
0e1b67 |
Use Cluster instead of Socket on the machine which doesn't have ACPI PPTT.
|
|
|
0e1b67 |
|
|
|
0e1b67 |
Note, ARM SBBR v1.2 requires ACPI PPTT, so this patch is needed for the
|
|
|
0e1b67 |
machine which is based on SBBR v1.0 and v1.1.
|
|
|
0e1b67 |
|
|
|
0e1b67 |
[kzak@redhat.com: - port to old code
|
|
|
0e1b67 |
- change semantic to be same as current upstream]
|
|
|
0e1b67 |
|
|
|
0e1b67 |
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1883056
|
|
|
0e1b67 |
Upstream: 73c0a766ffbe60e013b55cfd716d531b5a6ae22a
|
|
|
0e1b67 |
Upstream: https://marc.info/?l=util-linux-ng&m=159984070611464&w=2
|
|
|
0e1b67 |
Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
|
|
0e1b67 |
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
0e1b67 |
---
|
|
|
0e1b67 |
sys-utils/lscpu.1 | 3 +++
|
|
|
0e1b67 |
sys-utils/lscpu.c | 65 ++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
0e1b67 |
sys-utils/lscpu.h | 3 +++
|
|
|
0e1b67 |
3 files changed, 65 insertions(+), 6 deletions(-)
|
|
|
0e1b67 |
|
|
|
0e1b67 |
diff --git a/sys-utils/lscpu.1 b/sys-utils/lscpu.1
|
|
|
0e1b67 |
index b70f2e151..cf981d708 100644
|
|
|
0e1b67 |
--- a/sys-utils/lscpu.1
|
|
|
0e1b67 |
+++ b/sys-utils/lscpu.1
|
|
|
0e1b67 |
@@ -47,6 +47,9 @@ The logical core number. A core can contain several CPUs.
|
|
|
0e1b67 |
.B SOCKET
|
|
|
0e1b67 |
The logical socket number. A socket can contain several cores.
|
|
|
0e1b67 |
.TP
|
|
|
0e1b67 |
+.B CLUSTER
|
|
|
0e1b67 |
+The logical cluster number. A cluster can contain several cores.
|
|
|
0e1b67 |
+.TP
|
|
|
0e1b67 |
.B BOOK
|
|
|
0e1b67 |
The logical book number. A book can contain several sockets.
|
|
|
0e1b67 |
.TP
|
|
|
0e1b67 |
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
|
|
|
0e1b67 |
index 748d545b6..a8b448fa0 100644
|
|
|
0e1b67 |
--- a/sys-utils/lscpu.c
|
|
|
0e1b67 |
+++ b/sys-utils/lscpu.c
|
|
|
0e1b67 |
@@ -70,6 +70,7 @@
|
|
|
0e1b67 |
#define _PATH_SYS_HYP_FEATURES "/sys/hypervisor/properties/features"
|
|
|
0e1b67 |
#define _PATH_SYS_CPU _PATH_SYS_SYSTEM "/cpu"
|
|
|
0e1b67 |
#define _PATH_SYS_NODE _PATH_SYS_SYSTEM "/node"
|
|
|
0e1b67 |
+#define _PATH_ACPI_PPTT "/sys/firmware/acpi/tables/PPTT"
|
|
|
0e1b67 |
#define _PATH_PROC_XEN "/proc/xen"
|
|
|
0e1b67 |
#define _PATH_PROC_XENCAP _PATH_PROC_XEN "/capabilities"
|
|
|
0e1b67 |
#define _PATH_PROC_CPUINFO "/proc/cpuinfo"
|
|
|
0e1b67 |
@@ -168,6 +169,7 @@ enum {
|
|
|
0e1b67 |
COL_CPU,
|
|
|
0e1b67 |
COL_CORE,
|
|
|
0e1b67 |
COL_SOCKET,
|
|
|
0e1b67 |
+ COL_CLUSTER,
|
|
|
0e1b67 |
COL_NODE,
|
|
|
0e1b67 |
COL_BOOK,
|
|
|
0e1b67 |
COL_DRAWER,
|
|
|
0e1b67 |
@@ -194,6 +196,7 @@ static struct lscpu_coldesc coldescs[] =
|
|
|
0e1b67 |
[COL_CPU] = { "CPU", N_("logical CPU number"), 1 },
|
|
|
0e1b67 |
[COL_CORE] = { "CORE", N_("logical core number") },
|
|
|
0e1b67 |
[COL_SOCKET] = { "SOCKET", N_("logical socket number") },
|
|
|
0e1b67 |
+ [COL_CLUSTER] = { "CLUSTER", N_("logical cluster number") },
|
|
|
0e1b67 |
[COL_NODE] = { "NODE", N_("logical NUMA node number") },
|
|
|
0e1b67 |
[COL_BOOK] = { "BOOK", N_("logical book number") },
|
|
|
0e1b67 |
[COL_DRAWER] = { "DRAWER", N_("logical drawer number") },
|
|
|
0e1b67 |
@@ -383,6 +386,26 @@ static void read_physical_info_powerpc(
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
#endif
|
|
|
0e1b67 |
|
|
|
0e1b67 |
+static int is_fallback_to_cluster(struct lscpu_desc *desc)
|
|
|
0e1b67 |
+{
|
|
|
0e1b67 |
+ char *arch;
|
|
|
0e1b67 |
+ struct stat st;
|
|
|
0e1b67 |
+ struct utsname utsbuf;
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+ if (desc)
|
|
|
0e1b67 |
+ arch = desc->arch;
|
|
|
0e1b67 |
+ else {
|
|
|
0e1b67 |
+ if (uname(&utsbuf) == -1)
|
|
|
0e1b67 |
+ err(EXIT_FAILURE, _("error: uname failed"));
|
|
|
0e1b67 |
+ arch = utsbuf.machine;
|
|
|
0e1b67 |
+ }
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+ if (!(strcmp(arch, "aarch64")) && (stat(_PATH_ACPI_PPTT, &st) < 0))
|
|
|
0e1b67 |
+ return 1;
|
|
|
0e1b67 |
+ else
|
|
|
0e1b67 |
+ return 0;
|
|
|
0e1b67 |
+}
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
|
|
|
0e1b67 |
static void
|
|
|
0e1b67 |
read_basicinfo(struct lscpu_desc *desc, struct lscpu_modifier *mod)
|
|
|
0e1b67 |
@@ -1344,6 +1367,10 @@ get_cell_data(struct lscpu_desc *desc, int idx, int col,
|
|
|
0e1b67 |
snprintf(buf, bufsz, "%zu", i);
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
break;
|
|
|
0e1b67 |
+ case COL_CLUSTER:
|
|
|
0e1b67 |
+ if (!desc->is_cluster)
|
|
|
0e1b67 |
+ break;
|
|
|
0e1b67 |
+ /* fallthrough */
|
|
|
0e1b67 |
case COL_SOCKET:
|
|
|
0e1b67 |
if (mod->physical) {
|
|
|
0e1b67 |
if (desc->socketids[idx] == -1)
|
|
|
0e1b67 |
@@ -1799,12 +1826,18 @@ print_summary(struct lscpu_desc *desc, struct lscpu_modifier *mod)
|
|
|
0e1b67 |
if (fd)
|
|
|
0e1b67 |
fclose(fd);
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
if (desc->mtid)
|
|
|
0e1b67 |
threads_per_core = atoi(desc->mtid) + 1;
|
|
|
0e1b67 |
add_summary_n(tb, _("Thread(s) per core:"),
|
|
|
0e1b67 |
threads_per_core ?: desc->nthreads / desc->ncores);
|
|
|
0e1b67 |
- add_summary_n(tb, _("Core(s) per socket:"),
|
|
|
0e1b67 |
- cores_per_socket ?: desc->ncores / desc->nsockets);
|
|
|
0e1b67 |
+ if (desc->is_cluster)
|
|
|
0e1b67 |
+ add_summary_n(tb, _("Core(s) per cluster:"),
|
|
|
0e1b67 |
+ cores_per_socket ?: desc->ncores / desc->nsockets);
|
|
|
0e1b67 |
+ else
|
|
|
0e1b67 |
+ add_summary_n(tb, _("Core(s) per socket:"),
|
|
|
0e1b67 |
+ cores_per_socket ?: desc->ncores / desc->nsockets);
|
|
|
0e1b67 |
if (desc->nbooks) {
|
|
|
0e1b67 |
add_summary_n(tb, _("Socket(s) per book:"),
|
|
|
0e1b67 |
sockets_per_book ?: desc->nsockets / desc->nbooks);
|
|
|
0e1b67 |
@@ -1816,7 +1849,17 @@ print_summary(struct lscpu_desc *desc, struct lscpu_modifier *mod)
|
|
|
0e1b67 |
add_summary_n(tb, _("Book(s):"), books_per_drawer ?: desc->nbooks);
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
} else {
|
|
|
0e1b67 |
- add_summary_n(tb, _("Socket(s):"), sockets_per_book ?: desc->nsockets);
|
|
|
0e1b67 |
+ if (desc->is_cluster) {
|
|
|
0e1b67 |
+ if (desc->nr_socket_on_cluster > 0)
|
|
|
0e1b67 |
+ add_summary_n(tb, _("Socket(s):"), desc->nr_socket_on_cluster);
|
|
|
0e1b67 |
+ else
|
|
|
0e1b67 |
+ add_summary_s(tb, _("Socket(s):"), "-");
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+ add_summary_n(tb, _("Cluster(s):"),
|
|
|
0e1b67 |
+ sockets_per_book ?: desc->nsockets);
|
|
|
0e1b67 |
+ } else
|
|
|
0e1b67 |
+ add_summary_n(tb, _("Socket(s):"),
|
|
|
0e1b67 |
+ sockets_per_book ?: desc->nsockets);
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
if (desc->nnodes)
|
|
|
0e1b67 |
@@ -2060,10 +2103,13 @@ int main(int argc, char *argv[])
|
|
|
0e1b67 |
qsort(desc->ecaches, desc->necaches,
|
|
|
0e1b67 |
sizeof(struct cpu_cache), cachecmp);
|
|
|
0e1b67 |
|
|
|
0e1b67 |
+ desc->is_cluster = is_fallback_to_cluster(desc);
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
read_nodes(desc);
|
|
|
0e1b67 |
read_hypervisor(desc, mod);
|
|
|
0e1b67 |
arm_cpu_decode(desc);
|
|
|
0e1b67 |
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
switch(mod->mode) {
|
|
|
0e1b67 |
case OUTPUT_SUMMARY:
|
|
|
0e1b67 |
print_summary(desc, mod);
|
|
|
0e1b67 |
@@ -2072,7 +2118,10 @@ int main(int argc, char *argv[])
|
|
|
0e1b67 |
if (!ncolumns) {
|
|
|
0e1b67 |
columns[ncolumns++] = COL_CPU;
|
|
|
0e1b67 |
columns[ncolumns++] = COL_CORE;
|
|
|
0e1b67 |
- columns[ncolumns++] = COL_SOCKET;
|
|
|
0e1b67 |
+ if (desc->is_cluster)
|
|
|
0e1b67 |
+ columns[ncolumns++] = COL_CLUSTER;
|
|
|
0e1b67 |
+ else
|
|
|
0e1b67 |
+ columns[ncolumns++] = COL_SOCKET;
|
|
|
0e1b67 |
columns[ncolumns++] = COL_NODE;
|
|
|
0e1b67 |
columns[ncolumns++] = COL_CACHE;
|
|
|
0e1b67 |
mod->compat = 1;
|
|
|
0e1b67 |
@@ -2089,8 +2138,12 @@ int main(int argc, char *argv[])
|
|
|
0e1b67 |
columns[ncolumns++] = COL_DRAWER;
|
|
|
0e1b67 |
if (desc->bookmaps)
|
|
|
0e1b67 |
columns[ncolumns++] = COL_BOOK;
|
|
|
0e1b67 |
- if (desc->socketmaps)
|
|
|
0e1b67 |
- columns[ncolumns++] = COL_SOCKET;
|
|
|
0e1b67 |
+ if (desc->socketmaps) {
|
|
|
0e1b67 |
+ if (desc->is_cluster)
|
|
|
0e1b67 |
+ columns[ncolumns++] = COL_CLUSTER;
|
|
|
0e1b67 |
+ else
|
|
|
0e1b67 |
+ columns[ncolumns++] = COL_SOCKET;
|
|
|
0e1b67 |
+ }
|
|
|
0e1b67 |
if (desc->coremaps)
|
|
|
0e1b67 |
columns[ncolumns++] = COL_CORE;
|
|
|
0e1b67 |
if (desc->caches)
|
|
|
0e1b67 |
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
|
|
|
0e1b67 |
index 3d1885a3e..bffa9df60 100644
|
|
|
0e1b67 |
--- a/sys-utils/lscpu.h
|
|
|
0e1b67 |
+++ b/sys-utils/lscpu.h
|
|
|
0e1b67 |
@@ -158,6 +158,9 @@ struct lscpu_desc {
|
|
|
0e1b67 |
int physsockets; /* Physical sockets (modules) */
|
|
|
0e1b67 |
int physchips; /* Physical chips */
|
|
|
0e1b67 |
int physcoresperchip; /* Physical cores per chip */
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+ int is_cluster;
|
|
|
0e1b67 |
+ int nr_socket_on_cluster;
|
|
|
0e1b67 |
};
|
|
|
0e1b67 |
|
|
|
0e1b67 |
enum {
|
|
|
0e1b67 |
--
|
|
|
0e1b67 |
2.29.2
|
|
|
0e1b67 |
|