]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/topology: Use zero-based numbering for containing entities
authorAlexandra Winter <wintera@linux.ibm.com>
Wed, 22 Apr 2026 14:17:16 +0000 (16:17 +0200)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Wed, 20 May 2026 07:39:24 +0000 (09:39 +0200)
Start the numbering scheme for higher-level topology structures (like
socket, book, drawer) at zero, matching the convention for other hardware
identifiers like e.g. CPU numbers.

Hardware documentation, the Hardware Management Console and other tools
like zmemtopo also use zero-based numbering for these containing entities.
Aligning the numbering in sysfs, procfs, and tools like lscpu improves
user experience by making it easier to correlate topology information
across different interfaces.

If available, Linux on s390 derives this physical topology information from
the stsi function code 15 store_topology instruction, which is defined to
start at 1 for the lowest numbered container id. Subtract one, so
drawer_id, book_id and socket_id in cpu_topology[] start with 0 for the
lowest numbered entity; and /proc/cpuinfo and tools like 'lscpu -ye'
display the expected values.

Display only, no functional change intended.

Example: In a partition with 3 cores in a system with
8 cores per socket; 2 sockets per book; 4 books per dawer; and 4 drawers:
Before this fix:
$ lscpu -ye
CPU NODE DRAWER BOOK SOCKET CORE L1d:L1i:L2 ONLINE CONFIGURED POLARIZATION ADDRESS
  0    0      2    4      1    0 0:0:0         yes yes        vert-high    0
  1    0      2    4      1    0 1:1:1         yes yes        vert-high    1
  2    0      2    4      1    1 2:2:2         yes yes        vert-medium  2
  3    0      2    4      1    1 3:3:3         yes yes        vert-medium  3
  4    0      2    4      2    3 4:4:4         yes yes        vert-low     4
  5    0      2    4      2    3 5:5:5         yes yes        vert-low     5
After this fix:
$ lscpu -ye
CPU NODE DRAWER BOOK SOCKET CORE L1d:L1i:L2 ONLINE CONFIGURED POLARIZATION ADDRESS
  0    0      1    3      0    0 0:0:0         yes yes        vert-high    0
  1    0      1    3      0    0 1:1:1         yes yes        vert-high    1
  2    0      1    3      0    1 2:2:2         yes yes        vert-medium  2
  3    0      1    3      0    1 3:3:3         yes yes        vert-medium  3
  4    0      1    3      1    3 4:4:4         yes yes        vert-low     4
  5    0      1    3      1    3 5:5:5         yes yes        vert-low     5

For KVM guests, qemu emulates the stsi FC15 store_topology instruction.
This emulation currently erroneously starts id numbering at 0. A qemu fix
is proposed that makes this emulation compliant to the stsi architecture.
In case a guest with this patch is running on a qemu without the other fix,
it can happen that ids of 255 are displayed erroneously.

z/VM currently does not provide or emulate physical topology information to
its guests. So this patch does not change anything for z/VM guests.

Fixes: 10d385895055 ("[S390] topology: expose core identifier")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Acked-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/kernel/topology.c

index 1913a5566ac2b8609e97c2cc5378568dfd9a6f7d..1377c6f3f670958340fce997f83d48157fdc263e 100644 (file)
@@ -192,17 +192,21 @@ static void tl_to_masks(struct sysinfo_15_1_x *info)
        end = (union topology_entry *)((unsigned long)info + info->length);
        while (tle < end) {
                switch (tle->nl) {
+               /*
+                * Adjust drawer_id, book_id, and socked_id so they match the
+                * numbering scheme of e.g. the hardware management console.
+                */
                case 3:
                        drawer = drawer->next;
-                       drawer->id = tle->container.id;
+                       drawer->id = tle->container.id - 1;
                        break;
                case 2:
                        book = book->next;
-                       book->id = tle->container.id;
+                       book->id = tle->container.id - 1;
                        break;
                case 1:
                        socket = socket->next;
-                       socket->id = tle->container.id;
+                       socket->id = tle->container.id - 1;
                        break;
                case 0:
                        add_cpus_to_mask(&tle->cpu, drawer, book, socket);