]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: use cluster on aarch64 machine which doesn't have ACPI PPTT
authorMasayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Fri, 20 Nov 2020 05:06:05 +0000 (00:06 -0500)
committerKarel Zak <kzak@redhat.com>
Fri, 20 Nov 2020 08:17:12 +0000 (09:17 +0100)
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
sys-utils/lscpu.1
sys-utils/lscpu.c
sys-utils/lscpu.h

index 1cbc9775faad3b820c86504c72c0653b8cf2d894..9391cca54989c65e33050b94bea70b2c5681b64c 100644 (file)
@@ -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]);
 }
index ed14dc6630ec8d07d79f9eccb352580b4eb2a4ab..a4112539528b9d64d701e504f86483f5eb83f8ab 100644 (file)
@@ -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
index 1127d699999b3140774e40f8408901d4b1cacf79..65016f08b7c204463c25c789757f3b569ed94015 100644 (file)
@@ -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;
@@ -845,7 +851,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);
@@ -854,8 +863,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);
@@ -1327,8 +1342,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)
@@ -1352,7 +1371,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;
index 465bd3fe24636792c82b0ef4332cd83023db04a7..7d42816c3b799c65c954fb6c3c902503492a60f9 100644 (file)
@@ -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) \