Blame SOURCES/0051-lscpu-use-cluster-on-aarch64-machine-which-doesn-t-h.patch

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