util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine
@ 2020-11-20  5:06 Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 1/5] lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT Masayoshi Mizuma
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Masayoshi Mizuma @ 2020-11-20  5:06 UTC (permalink / raw)
  To: util-linux; +Cc: Masayoshi Mizuma

lscpu may show the wrong number of physical sockets on aarch64 machine
as 'Socket(s)'.

That is because lscpu uses a sysfs entry (cpu/cpuX/topology/core_siblings) to
get the number of sockets. For aarch64, the sysfs entry is set from MPIDR_EL1
register if the machine doesn't have ACPI PPTT. According to ARM Architecture
Reference Manual, the register shows the topology as the affinity, but doesn't
show the physical socket information.

There are such aarch64 machines because ARM SBBR v1.0 and v1.1 don't require 
ACPI PPTT. SBBR v1.2 requires ACPI PPTT.

For the aarch64 machine, probably 'Cluster(s)' is good instead of 'Socket(s)'
according to linux/arch/arm64/kernel/topology.c:store_cpu_topology().

To get the number of sockets on the machine, SMBIOS Processor information (Type04)
is useful for lscpu because the SMBIOS information is a mandatory
feature for the aarch64 machine which is based on ARM SBBR v1.0 and newer.

With these patches, lscpu shows as following on the machine:

  For unprivileged user:
    $ lscpu 
    Architecture:            aarch64
    ...
        Socket(s):           -
        Cluster(s):          4

  For root:
    # lscpu 
    Architecture:            aarch64
    ...
        Socket(s):           1
        Cluster(s):          4

Changelog:
        v3: Remove cluster/socket column checking. Make lscpu_is_cluster_arm()
            static (0001 patch)
	v2: Rebased to the latest lscpu

Masayoshi Mizuma (5):
  lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT
  lscpu-virt: split hypervisor_from_dmi_table()
  lscpu-dmi: Move some functions related to DMI to lscpu-dmi
  lscpu: add helper to get physical sockets
  lscpu: show the number of physical socket on aarch64 machine without
    ACPI PPTT

 sys-utils/Makemodule.am |   1 +
 sys-utils/lscpu-arm.c   |  15 ++++++
 sys-utils/lscpu-dmi.c   | 108 ++++++++++++++++++++++++++++++++++++++++
 sys-utils/lscpu-virt.c  |  62 ++++++-----------------
 sys-utils/lscpu.1       |   3 ++
 sys-utils/lscpu.c       |  39 ++++++++++++---
 sys-utils/lscpu.h       |  38 ++++++--------
 7 files changed, 190 insertions(+), 76 deletions(-)
 create mode 100644 sys-utils/lscpu-dmi.c

-- 
2.27.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/5] lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT
  2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
@ 2020-11-20  5:06 ` Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 2/5] lscpu-virt: split hypervisor_from_dmi_table() Masayoshi Mizuma
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Masayoshi Mizuma @ 2020-11-20  5:06 UTC (permalink / raw)
  To: util-linux; +Cc: Masayoshi Mizuma, Masayoshi Mizuma

From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>

lscpu may show the wrong number of sockets if the machine is aarch64 and
doesn't have ACPI PPTT.

That's because lscpu shows the number of sockets by using a sysfs entry
(cpu/cpuX/topology/core_siblings). The sysfs entry is set by MPIDR_EL1
register if the machine doesn't have ACPI PPTT. MPIDR_EL1 doesn't show
the physical socket information directly. It shows the affinity level.

According to linux/arch/arm64/kernel/topology.c:store_cpu_topology(),
the top level of affinity is called as 'Cluster'.

Use Cluster instead of Socket on the machine which doesn't have ACPI PPTT.

This patch is useful for aarch64 machine which is based on ARM
SBBR v1.0 and v1.1, the specs don't require ACPI PPTT. ARM SBBR v1.2
requires ACPI PPTT.

Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
---
 sys-utils/lscpu-arm.c | 13 +++++++++++++
 sys-utils/lscpu.1     |  3 +++
 sys-utils/lscpu.c     | 34 ++++++++++++++++++++++++++++------
 sys-utils/lscpu.h     |  2 ++
 4 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/sys-utils/lscpu-arm.c b/sys-utils/lscpu-arm.c
index 1cbc9775f..9391cca54 100644
--- a/sys-utils/lscpu-arm.c
+++ b/sys-utils/lscpu-arm.c
@@ -362,10 +362,23 @@ static void arm_decode(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
 	arm_rXpY_decode(ct);
 }
 
+static int lscpu_is_cluster_arm(struct lscpu_cxt *cxt)
+{
+	struct stat st;
+
+	if (!(strcmp(cxt->arch->name, "aarch64")) &&
+	     (stat(_PATH_ACPI_PPTT, &st) < 0) && (cxt->ncputypes == 1))
+		return 1;
+	else
+		return 0;
+}
+
 void lscpu_decode_arm(struct lscpu_cxt *cxt)
 {
 	size_t i;
 
+	cxt->is_cluster = lscpu_is_cluster_arm(cxt);
+
 	for (i = 0; i < cxt->ncputypes; i++)
 		arm_decode(cxt, cxt->cputypes[i]);
 }
diff --git a/sys-utils/lscpu.1 b/sys-utils/lscpu.1
index ed14dc663..a41125395 100644
--- a/sys-utils/lscpu.1
+++ b/sys-utils/lscpu.1
@@ -55,6 +55,9 @@ The logical core number.  A core can contain several CPUs.
 .B SOCKET
 The logical socket number.  A socket can contain several cores.
 .TP
+.B CLUSTER
+The logical cluster number.  A cluster can contain several cores.
+.TP
 .B BOOK
 The logical book number.  A book can contain several sockets.
 .TP
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
index 6e501b044..b9b8940a8 100644
--- a/sys-utils/lscpu.c
+++ b/sys-utils/lscpu.c
@@ -95,6 +95,7 @@ enum {
 	COL_CPU_CPU,
 	COL_CPU_CORE,
 	COL_CPU_SOCKET,
+	COL_CPU_CLUSTER,
 	COL_CPU_NODE,
 	COL_CPU_BOOK,
 	COL_CPU_DRAWER,
@@ -138,6 +139,7 @@ static struct lscpu_coldesc coldescs_cpu[] =
 	[COL_CPU_BOGOMIPS]     = { "BOGOMIPS", N_("crude measurement of CPU speed"), SCOLS_FL_RIGHT, 1 },
 	[COL_CPU_CPU]          = { "CPU", N_("logical CPU number"), SCOLS_FL_RIGHT, 1 },
 	[COL_CPU_CORE]         = { "CORE", N_("logical core number"), SCOLS_FL_RIGHT },
+	[COL_CPU_CLUSTER]      = { "CLUSTER", N_("logical cluster number"), SCOLS_FL_RIGHT },
 	[COL_CPU_SOCKET]       = { "SOCKET", N_("logical socket number"), SCOLS_FL_RIGHT },
 	[COL_CPU_NODE]         = { "NODE", N_("logical NUMA node number"), SCOLS_FL_RIGHT },
 	[COL_CPU_BOOK]         = { "BOOK", N_("logical book number"), SCOLS_FL_RIGHT },
@@ -339,6 +341,10 @@ static char *get_cell_data(
 	case COL_CPU_SOCKET:
 		fill_id(cxt, cpu, socket, buf, bufsz);
 		break;
+	case COL_CPU_CLUSTER:
+		if (cxt->is_cluster)
+			fill_id(cxt, cpu, socket, buf, bufsz);
+		break;
 	case COL_CPU_DRAWER:
 		fill_id(cxt, cpu, drawer, buf, bufsz);
 		break;
@@ -843,7 +849,10 @@ print_summary_cputype(struct lscpu_cxt *cxt,
 		add_summary_s(tb, sec, _("Model:"), ct->revision ? ct->revision : ct->model);
 
 	add_summary_n(tb, sec, _("Thread(s) per core:"), ct->nthreads_per_core);
-	add_summary_n(tb, sec, _("Core(s) per socket:"), ct->ncores_per_socket);
+	if (cxt->is_cluster)
+		add_summary_n(tb, sec, _("Core(s) per cluster:"), ct->ncores_per_socket);
+	else
+		add_summary_n(tb, sec, _("Core(s) per socket:"), ct->ncores_per_socket);
 
 	if (ct->nbooks) {
 		add_summary_n(tb, sec, _("Socket(s) per book:"), ct->nsockets_per_book);
@@ -852,8 +861,14 @@ print_summary_cputype(struct lscpu_cxt *cxt,
 			add_summary_n(tb, sec, _("Drawer(s):"), ct->ndrawers_per_system ?: ct->ndrawers);
 		} else
 			add_summary_n(tb, sec, _("Book(s):"), ct->nbooks_per_drawer ?: ct->nbooks);
-	} else
-		add_summary_n(tb, sec, _("Socket(s):"), ct->nsockets_per_book ?: ct->nsockets);
+	} else {
+		if (cxt->is_cluster)
+			add_summary_n(tb, sec, _("Cluster(s):"),
+					ct->nsockets_per_book ?: ct->nsockets);
+		else
+			add_summary_n(tb, sec, _("Socket(s):"),
+					ct->nsockets_per_book ?: ct->nsockets);
+	}
 
 	if (ct->stepping)
 		add_summary_s(tb, sec, _("Stepping:"), ct->stepping);
@@ -1325,8 +1340,12 @@ int main(int argc, char *argv[])
 				columns[ncolumns++] = COL_CPU_DRAWER;
 			if (ct && ct->nbooks)
 				columns[ncolumns++] = COL_CPU_BOOK;
-			if (ct && ct->nsockets)
-				columns[ncolumns++] = COL_CPU_SOCKET;
+			if (ct && ct->nsockets) {
+				if (cxt->is_cluster)
+					columns[ncolumns++] = COL_CPU_CLUSTER;
+				else
+					columns[ncolumns++] = COL_CPU_SOCKET;
+			}
 			if (ct && ct->ncores)
 				columns[ncolumns++] = COL_CPU_CORE;
 			if (cxt->ncaches)
@@ -1350,7 +1369,10 @@ int main(int argc, char *argv[])
 		if (!ncolumns) {
 			columns[ncolumns++] = COL_CPU_CPU;
 			columns[ncolumns++] = COL_CPU_CORE;
-			columns[ncolumns++] = COL_CPU_SOCKET;
+			if (cxt->is_cluster)
+				columns[ncolumns++] = COL_CPU_CLUSTER;
+			else
+				columns[ncolumns++] = COL_CPU_SOCKET;
 			columns[ncolumns++] = COL_CPU_NODE;
 			columns[ncolumns++] = COL_CPU_CACHE;
 			cxt->show_compatible = 1;
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 465bd3fe2..7d42816c3 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -33,6 +33,7 @@ UL_DEBUG_DECLARE_MASK(lscpu);
 #define _PATH_SYS_NODE		_PATH_SYS_SYSTEM "/node"
 #define _PATH_SYS_DMI		"/sys/firmware/dmi/tables/DMI"
 #define _PATH_SYS_DMI_TYPE4	"/sys/firmware/dmi/entries/4-0/raw"
+#define _PATH_ACPI_PPTT		"/sys/firmware/acpi/tables/PPTT"
 
 struct lscpu_cache {
 	int		id;		/* unique identifier */
@@ -242,6 +243,7 @@ struct lscpu_cxt {
 		     json : 1,
 		     bytes : 1;
 
+	int is_cluster; /* For aarch64 if the machine doesn't have ACPI PPTT */
 };
 
 #define is_cpu_online(_cxt, _cpu) \
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/5] lscpu-virt: split hypervisor_from_dmi_table()
  2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 1/5] lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT Masayoshi Mizuma
@ 2020-11-20  5:06 ` Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 3/5] lscpu-dmi: Move some functions related to DMI to lscpu-dmi Masayoshi Mizuma
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Masayoshi Mizuma @ 2020-11-20  5:06 UTC (permalink / raw)
  To: util-linux; +Cc: Masayoshi Mizuma, Masayoshi Mizuma

From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>

Split hypervisor_from_dmi_table() to parsing dmi table and checking the
hypervisor vendor.

Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
---
 sys-utils/lscpu-virt.c | 54 ++++++++++++++++++++++++++----------------
 sys-utils/lscpu.h      |  6 +++++
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/sys-utils/lscpu-virt.c b/sys-utils/lscpu-virt.c
index 8d7c9b740..c86dae8c9 100644
--- a/sys-utils/lscpu-virt.c
+++ b/sys-utils/lscpu-virt.c
@@ -76,20 +76,13 @@ nothing:
 	return NULL;
 }
 
-static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
-				uint16_t num, const char *devmem)
+static int parse_dmi_table(uint16_t len, uint16_t num,
+				uint8_t *data,
+				struct dmi_info *di)
 {
-	uint8_t *buf;
-	uint8_t *data;
+	uint8_t *buf = data;
+	int rc = -1;
 	int i = 0;
-	char *vendor = NULL;
-	char *product = NULL;
-	char *manufacturer = NULL;
-	int rc = VIRT_VENDOR_NONE;
-
-	data = buf = get_mem_chunk(base, len, devmem);
-	if (!buf)
-		goto done;
 
 	 /* 4 is the length of an SMBIOS structure header */
 	while (i < num && data + 4 <= buf + len) {
@@ -113,11 +106,11 @@ static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
 		next += 2;
 		switch (h.type) {
 			case 0:
-				vendor = dmi_string(&h, data[0x04]);
+				di->vendor = dmi_string(&h, data[0x04]);
 				break;
 			case 1:
-				manufacturer = dmi_string(&h, data[0x04]);
-				product = dmi_string(&h, data[0x05]);
+				di->manufacturer = dmi_string(&h, data[0x04]);
+				di->product = dmi_string(&h, data[0x05]);
 				break;
 			default:
 				break;
@@ -126,15 +119,36 @@ static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
 		data = next;
 		i++;
 	}
-	if (manufacturer && !strcmp(manufacturer, "innotek GmbH"))
+	rc = 0;
+done:
+	return rc;
+}
+
+static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
+				uint16_t num, const char *devmem)
+{
+	uint8_t *data;
+	int rc = VIRT_VENDOR_NONE;
+	struct dmi_info di;
+
+	data = get_mem_chunk(base, len, devmem);
+	if (!data)
+		return rc;
+
+	memset(&di, 0, sizeof(struct dmi_info));
+	rc = parse_dmi_table(len, num, data, &di);
+	if (rc < 0)
+		goto done;
+
+	if (di.manufacturer && !strcmp(di.manufacturer, "innotek GmbH"))
 		rc = VIRT_VENDOR_INNOTEK;
-	else if (manufacturer && strstr(manufacturer, "HITACHI") &&
-					product && strstr(product, "LPAR"))
+	else if (di.manufacturer && strstr(di.manufacturer, "HITACHI") &&
+					di.product && strstr(di.product, "LPAR"))
 		rc = VIRT_VENDOR_HITACHI;
-	else if (vendor && !strcmp(vendor, "Parallels"))
+	else if (di.vendor && !strcmp(di.vendor, "Parallels"))
 		rc = VIRT_VENDOR_PARALLELS;
 done:
-	free(buf);
+	free(data);
 	return rc;
 }
 
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 7d42816c3..11b27fb14 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -305,6 +305,12 @@ struct lscpu_dmi_header
 	uint8_t *data;
 };
 
+struct dmi_info {
+	char *vendor;
+	char *product;
+	char *manufacturer;
+};
+
 static inline void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data)
 {
 	h->type = data[0];
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/5] lscpu-dmi: Move some functions related to DMI to lscpu-dmi
  2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 1/5] lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 2/5] lscpu-virt: split hypervisor_from_dmi_table() Masayoshi Mizuma
@ 2020-11-20  5:06 ` Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 4/5] lscpu: add helper to get physical sockets Masayoshi Mizuma
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Masayoshi Mizuma @ 2020-11-20  5:06 UTC (permalink / raw)
  To: util-linux; +Cc: Masayoshi Mizuma, Masayoshi Mizuma

From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>

Move some functions related to DMI to lscpu-dmi.

Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
---
 sys-utils/Makemodule.am |  1 +
 sys-utils/lscpu-dmi.c   | 79 +++++++++++++++++++++++++++++++++++++++++
 sys-utils/lscpu-virt.c  | 50 +-------------------------
 sys-utils/lscpu.h       | 28 +++------------
 4 files changed, 86 insertions(+), 72 deletions(-)
 create mode 100644 sys-utils/lscpu-dmi.c

diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 5459a3a2e..df8fd403a 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -396,6 +396,7 @@ lscpu_SOURCES = sys-utils/lscpu.c \
 		sys-utils/lscpu-topology.c \
 		sys-utils/lscpu-virt.c \
 		sys-utils/lscpu-arm.c \
+		sys-utils/lscpu-dmi.c \
 		sys-utils/lscpu.h
 lscpu_LDADD = $(LDADD) libcommon.la libsmartcols.la $(RTAS_LIBS)
 lscpu_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c
new file mode 100644
index 000000000..00d4439f8
--- /dev/null
+++ b/sys-utils/lscpu-dmi.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 FUJITSU LIMITED.  All rights reserved.
+ */
+
+#include "lscpu.h"
+
+void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data)
+{
+	h->type = data[0];
+	h->length = data[1];
+	memcpy(&h->handle, data + 2, sizeof(h->handle));
+	h->data = data;
+}
+
+char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s)
+{
+	char *bp = (char *)dm->data;
+
+	if (!s || !bp)
+		return NULL;
+
+	bp += dm->length;
+	while (s > 1 && *bp) {
+		bp += strlen(bp);
+		bp++;
+		s--;
+	}
+
+	return !*bp ? NULL : bp;
+}
+
+int parse_dmi_table(uint16_t len, uint16_t num,
+				uint8_t *data,
+				struct dmi_info *di)
+{
+	uint8_t *buf = data;
+	int rc = -1;
+	int i = 0;
+
+	 /* 4 is the length of an SMBIOS structure header */
+	while (i < num && data + 4 <= buf + len) {
+		uint8_t *next;
+		struct lscpu_dmi_header h;
+
+		to_dmi_header(&h, data);
+
+		/*
+		 * If a short entry is found (less than 4 bytes), not only it
+		 * is invalid, but we cannot reliably locate the next entry.
+		 * Better stop at this point.
+		 */
+		if (h.length < 4)
+			goto done;
+
+		/* look for the next handle */
+		next = data + h.length;
+		while (next - buf + 1 < len && (next[0] != 0 || next[1] != 0))
+			next++;
+		next += 2;
+		switch (h.type) {
+		case 0:
+			di->vendor = dmi_string(&h, data[0x04]);
+			break;
+		case 1:
+			di->manufacturer = dmi_string(&h, data[0x04]);
+			di->product = dmi_string(&h, data[0x05]);
+			break;
+		default:
+			break;
+		}
+
+		data = next;
+		i++;
+	}
+	rc = 0;
+done:
+	return rc;
+}
diff --git a/sys-utils/lscpu-virt.c b/sys-utils/lscpu-virt.c
index c86dae8c9..9b61eb6f8 100644
--- a/sys-utils/lscpu-virt.c
+++ b/sys-utils/lscpu-virt.c
@@ -52,7 +52,7 @@ static const int hv_graphics_pci[] = {
 #define WORD(x) (uint16_t)(*(const uint16_t *)(x))
 #define DWORD(x) (uint32_t)(*(const uint32_t *)(x))
 
-static void *get_mem_chunk(size_t base, size_t len, const char *devmem)
+void *get_mem_chunk(size_t base, size_t len, const char *devmem)
 {
 	void *p = NULL;
 	int fd;
@@ -76,54 +76,6 @@ nothing:
 	return NULL;
 }
 
-static int parse_dmi_table(uint16_t len, uint16_t num,
-				uint8_t *data,
-				struct dmi_info *di)
-{
-	uint8_t *buf = data;
-	int rc = -1;
-	int i = 0;
-
-	 /* 4 is the length of an SMBIOS structure header */
-	while (i < num && data + 4 <= buf + len) {
-		uint8_t *next;
-		struct lscpu_dmi_header h;
-
-		to_dmi_header(&h, data);
-
-		/*
-		 * If a short entry is found (less than 4 bytes), not only it
-		 * is invalid, but we cannot reliably locate the next entry.
-		 * Better stop at this point.
-		 */
-		if (h.length < 4)
-			goto done;
-
-		/* look for the next handle */
-		next = data + h.length;
-		while (next - buf + 1 < len && (next[0] != 0 || next[1] != 0))
-			next++;
-		next += 2;
-		switch (h.type) {
-			case 0:
-				di->vendor = dmi_string(&h, data[0x04]);
-				break;
-			case 1:
-				di->manufacturer = dmi_string(&h, data[0x04]);
-				di->product = dmi_string(&h, data[0x05]);
-				break;
-			default:
-				break;
-		}
-
-		data = next;
-		i++;
-	}
-	rc = 0;
-done:
-	return rc;
-}
-
 static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
 				uint16_t num, const char *devmem)
 {
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 11b27fb14..9ec3fca17 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -297,6 +297,8 @@ void lscpu_decode_arm(struct lscpu_cxt *cxt);
 
 int lookup(char *line, char *pattern, char **value);
 
+void *get_mem_chunk(size_t base, size_t len, const char *devmem);
+
 struct lscpu_dmi_header
 {
 	uint8_t type;
@@ -311,28 +313,8 @@ struct dmi_info {
 	char *manufacturer;
 };
 
-static inline void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data)
-{
-	h->type = data[0];
-	h->length = data[1];
-	memcpy(&h->handle, data + 2, sizeof(h->handle));
-	h->data = data;
-}
-
-static inline char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s)
-{
-	char *bp = (char *)dm->data;
-
-	if (!s || !bp)
-		return NULL;
-
-	bp += dm->length;
-	while (s > 1 && *bp) {
-		bp += strlen(bp);
-		bp++;
-		s--;
-	}
 
-	return !*bp ? NULL : bp;
-}
+void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data);
+char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s);
+int parse_dmi_table(uint16_t len, uint16_t num, uint8_t *data, struct dmi_info *di);
 #endif /* LSCPU_H */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 4/5] lscpu: add helper to get physical sockets
  2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
                   ` (2 preceding siblings ...)
  2020-11-20  5:06 ` [PATCH v3 3/5] lscpu-dmi: Move some functions related to DMI to lscpu-dmi Masayoshi Mizuma
@ 2020-11-20  5:06 ` Masayoshi Mizuma
  2020-11-20  5:06 ` [PATCH v3 5/5] lscpu: show the number of physical socket on aarch64 machine without ACPI PPTT Masayoshi Mizuma
  2020-11-20  9:07 ` [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Karel Zak
  5 siblings, 0 replies; 7+ messages in thread
From: Masayoshi Mizuma @ 2020-11-20  5:06 UTC (permalink / raw)
  To: util-linux; +Cc: Masayoshi Mizuma, Masayoshi Mizuma

From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>

Add a helper function, get_number_of_physical_sockets_from_dmi(),
to get physical sockets from DMI table in case of the sysfs for
cpu topology doesn't have the physical socket information.

get_number_of_physical_sockets_from_dmi() parse the DMI table
and counts the number of SMBIOS Processor Information (Type04)
structure.

Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
---
 sys-utils/lscpu-dmi.c | 29 +++++++++++++++++++++++++++++
 sys-utils/lscpu.h     |  2 ++
 2 files changed, 31 insertions(+)

diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c
index 00d4439f8..e7ffa88d3 100644
--- a/sys-utils/lscpu-dmi.c
+++ b/sys-utils/lscpu-dmi.c
@@ -66,6 +66,9 @@ int parse_dmi_table(uint16_t len, uint16_t num,
 			di->manufacturer = dmi_string(&h, data[0x04]);
 			di->product = dmi_string(&h, data[0x05]);
 			break;
+		case 4:
+			di->sockets++;
+			break;
 		default:
 			break;
 		}
@@ -77,3 +80,29 @@ int parse_dmi_table(uint16_t len, uint16_t num,
 done:
 	return rc;
 }
+
+size_t get_number_of_physical_sockets_from_dmi(void)
+{
+	static char const sys_fw_dmi_tables[] = _PATH_SYS_DMI;
+	struct dmi_info di;
+	struct stat st;
+	uint8_t *data;
+	int rc = 0;
+
+	if (stat(sys_fw_dmi_tables, &st))
+		return rc;
+
+	data = get_mem_chunk(0, st.st_size, sys_fw_dmi_tables);
+	if (!data)
+		return rc;
+
+	memset(&di, 0, sizeof(struct dmi_info));
+	rc = parse_dmi_table(st.st_size, st.st_size/4, data, &di);
+
+	free(data);
+
+	if ((rc < 0) || !di.sockets)
+		return 0;
+	else
+		return di.sockets;
+}
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 9ec3fca17..74c647e3a 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -311,10 +311,12 @@ struct dmi_info {
 	char *vendor;
 	char *product;
 	char *manufacturer;
+	int sockets;
 };
 
 
 void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data);
 char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s);
 int parse_dmi_table(uint16_t len, uint16_t num, uint8_t *data, struct dmi_info *di);
+size_t get_number_of_physical_sockets_from_dmi(void);
 #endif /* LSCPU_H */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 5/5] lscpu: show the number of physical socket on aarch64 machine without ACPI PPTT
  2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
                   ` (3 preceding siblings ...)
  2020-11-20  5:06 ` [PATCH v3 4/5] lscpu: add helper to get physical sockets Masayoshi Mizuma
@ 2020-11-20  5:06 ` Masayoshi Mizuma
  2020-11-20  9:07 ` [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Karel Zak
  5 siblings, 0 replies; 7+ messages in thread
From: Masayoshi Mizuma @ 2020-11-20  5:06 UTC (permalink / raw)
  To: util-linux; +Cc: Masayoshi Mizuma, Masayoshi Mizuma

From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>

Show the number of the number of physical socket even if the sysfs doesn't
have the physical socket information.

Note, lscpu shows the number of physical socket as 'Socket(s):' only if
root user runs it because accessing the DMI table requires root
privilege.

Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
---
 sys-utils/lscpu-arm.c | 2 ++
 sys-utils/lscpu.c     | 9 +++++++--
 sys-utils/lscpu.h     | 2 ++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sys-utils/lscpu-arm.c b/sys-utils/lscpu-arm.c
index 9391cca54..9e259673c 100644
--- a/sys-utils/lscpu-arm.c
+++ b/sys-utils/lscpu-arm.c
@@ -360,6 +360,8 @@ static void arm_decode(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
 
 	arm_ids_decode(ct);
 	arm_rXpY_decode(ct);
+	if (cxt->is_cluster)
+		ct->nr_socket_on_cluster = get_number_of_physical_sockets_from_dmi();
 }
 
 static int lscpu_is_cluster_arm(struct lscpu_cxt *cxt)
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
index b9b8940a8..85d1d0acb 100644
--- a/sys-utils/lscpu.c
+++ b/sys-utils/lscpu.c
@@ -862,10 +862,15 @@ print_summary_cputype(struct lscpu_cxt *cxt,
 		} else
 			add_summary_n(tb, sec, _("Book(s):"), ct->nbooks_per_drawer ?: ct->nbooks);
 	} else {
-		if (cxt->is_cluster)
+		if (cxt->is_cluster) {
+			if (ct->nr_socket_on_cluster > 0)
+				add_summary_n(tb, sec, _("Socket(s):"), ct->nr_socket_on_cluster);
+			else
+				add_summary_s(tb, sec, _("Socket(s):"), "-");
+
 			add_summary_n(tb, sec, _("Cluster(s):"),
 					ct->nsockets_per_book ?: ct->nsockets);
-		else
+		} else
 			add_summary_n(tb, sec, _("Socket(s):"),
 					ct->nsockets_per_book ?: ct->nsockets);
 	}
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 74c647e3a..623c07998 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -101,6 +101,8 @@ struct lscpu_cputype {
 			has_configured : 1,
 			has_polarization : 1,
 			has_addresses : 1;
+
+	size_t nr_socket_on_cluster; /* the number of sockets if the is_cluster is 1 */
 };
 
 /* dispatching modes */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine
  2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
                   ` (4 preceding siblings ...)
  2020-11-20  5:06 ` [PATCH v3 5/5] lscpu: show the number of physical socket on aarch64 machine without ACPI PPTT Masayoshi Mizuma
@ 2020-11-20  9:07 ` Karel Zak
  5 siblings, 0 replies; 7+ messages in thread
From: Karel Zak @ 2020-11-20  9:07 UTC (permalink / raw)
  To: Masayoshi Mizuma; +Cc: util-linux

On Fri, Nov 20, 2020 at 12:06:04AM -0500, Masayoshi Mizuma wrote:
> Masayoshi Mizuma (5):
>   lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT
>   lscpu-virt: split hypervisor_from_dmi_table()
>   lscpu-dmi: Move some functions related to DMI to lscpu-dmi
>   lscpu: add helper to get physical sockets
>   lscpu: show the number of physical socket on aarch64 machine without
>     ACPI PPTT
> 
>  sys-utils/Makemodule.am |   1 +
>  sys-utils/lscpu-arm.c   |  15 ++++++
>  sys-utils/lscpu-dmi.c   | 108 ++++++++++++++++++++++++++++++++++++++++
>  sys-utils/lscpu-virt.c  |  62 ++++++-----------------
>  sys-utils/lscpu.1       |   3 ++
>  sys-utils/lscpu.c       |  39 ++++++++++++---
>  sys-utils/lscpu.h       |  38 ++++++--------
>  7 files changed, 190 insertions(+), 76 deletions(-)
>  create mode 100644 sys-utils/lscpu-dmi.c


Applied, thanks!

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-20  9:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20  5:06 [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Masayoshi Mizuma
2020-11-20  5:06 ` [PATCH v3 1/5] lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT Masayoshi Mizuma
2020-11-20  5:06 ` [PATCH v3 2/5] lscpu-virt: split hypervisor_from_dmi_table() Masayoshi Mizuma
2020-11-20  5:06 ` [PATCH v3 3/5] lscpu-dmi: Move some functions related to DMI to lscpu-dmi Masayoshi Mizuma
2020-11-20  5:06 ` [PATCH v3 4/5] lscpu: add helper to get physical sockets Masayoshi Mizuma
2020-11-20  5:06 ` [PATCH v3 5/5] lscpu: show the number of physical socket on aarch64 machine without ACPI PPTT Masayoshi Mizuma
2020-11-20  9:07 ` [PATCH v3 0/5] lscpu: Fix socket information on aarch64 machine Karel Zak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).