]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
powerpc/smp: Expose die_id and die_cpumask
authorSrikar Dronamraju <srikar@linux.ibm.com>
Wed, 12 Nov 2025 07:48:59 +0000 (13:18 +0530)
committerMadhavan Srinivasan <maddy@linux.ibm.com>
Fri, 14 Nov 2025 05:42:56 +0000 (11:12 +0530)
>From Power10 processors onwards, each chip has 2 hemispheres. For LPARs
running on PowerVM Hypervisor, hypervisor determines the allocation of
CPU groups to each LPAR, resulting in two LPARs with the same number of
CPUs potentially having different numbers of CPUs from each hemisphere.
Additionally, it is not feasible to ascertain the hemisphere based
solely on the CPU number.

Users wishing to assign their workload to all CPUs, or a subset of CPUs
within a specific hemisphere, encounter difficulties in identifying the
cpumask. To address this, it is proposed to expose hemisphere
information as a die in sysfs. This aligns with other architectures
and facilitates the identification of CPUs within the same hemisphere.
Tools such as lstopo can also access this information.

Please note: The hypervisor reveals the locality of the CPUs to
hemispheres only in dedicated mode. Consequently, in systems where
hemisphere information is unavailable, such as shared LPARs, the
die_cpus information in sysfs will mirror package_cpus, with
die_id set to -1.

Without this change.
$ grep . /sys/devices/system/cpu/cpu16/topology/{die*,package*} 2>/dev/null
/sys/devices/system/cpu/cpu16/topology/package_cpus:000000,000000ff,ffff0000
/sys/devices/system/cpu/cpu16/topology/package_cpus_list:16-39

With this change.
$ grep . /sys/devices/system/cpu/cpu16/topology/{die*,package*} 2>/dev/null
/sys/devices/system/cpu/cpu16/topology/die_cpus:000000,00000000,00ff0000
/sys/devices/system/cpu/cpu16/topology/die_cpus_list:16-23
/sys/devices/system/cpu/cpu16/topology/die_id:2
/sys/devices/system/cpu/cpu16/topology/package_cpus:000000,000000ff,ffff0000
/sys/devices/system/cpu/cpu16/topology/package_cpus_list:16-39

snipped lstopo-no-graphics o/p
  Group0 L#0 (total=8747584KB)
    Package L#0 (total=3564096KB CPUModel="POWER10 (architected), altivec supported" CPURevision="2.0 (pvr 0080 0200)")
      NUMANode L#0 (P#0 local=3564096KB total=3564096KB)
      Die L#0 (P#0)
        Core L#0 (P#0)
<snipped>
    Package L#1 (total=5183488KB CPUModel="POWER10 (architected), altivec supported" CPURevision="2.0 (pvr 0080 0200)")
      NUMANode L#1 (P#1 local=5183488KB total=5183488KB)
      Die L#2 (P#2)
        Core L#2 (P#16)
          L3Cache L#4 (size=4096KB linesize=128 ways=16)
            L2Cache L#4 (size=1024KB linesize=128 ways=8)
              L1dCache L#4 (size=32KB linesize=128 ways=8)
                L1iCache L#4 (size=48KB linesize=128 ways=6)
                  PU L#16 (P#16)
                  PU L#17 (P#18)
                  PU L#18 (P#20)
                  PU L#19 (P#22)
          L3Cache L#5 (size=4096KB linesize=128 ways=16)
            L2Cache L#5 (size=1024KB linesize=128 ways=8)
              L1dCache L#5 (size=32KB linesize=128 ways=8)
                L1iCache L#5 (size=48KB linesize=128 ways=6)
                  PU L#20 (P#17)
                  PU L#21 (P#19)
                  PU L#22 (P#21)
                  PU L#23 (P#23)
      Die L#3 (P#3)
        Core L#3 (P#24)
          L3Cache L#6 (size=4096KB linesize=128 ways=16)
            L2Cache L#6 (size=1024KB linesize=128 ways=8)
              L1dCache L#6 (size=32KB linesize=128 ways=8)
                L1iCache L#6 (size=48KB linesize=128 ways=6)
                  PU L#24 (P#24)
                  PU L#25 (P#26)
                  PU L#26 (P#28)
                  PU L#27 (P#30)
          L3Cache L#7 (size=4096KB linesize=128 ways=16)
            L2Cache L#7 (size=1024KB linesize=128 ways=8)
              L1dCache L#7 (size=32KB linesize=128 ways=8)
                L1iCache L#7 (size=48KB linesize=128 ways=6)
                  PU L#28 (P#25)
                  PU L#29 (P#27)
                  PU L#30 (P#29)
                  PU L#31 (P#31)
        Core L#4 (P#32)
          L3Cache L#8 (size=4096KB linesize=128 ways=16)
            L2Cache L#8 (size=1024KB linesize=128 ways=8)
              L1dCache L#8 (size=32KB linesize=128 ways=8)
                L1iCache L#8 (size=48KB linesize=128 ways=6)
                  PU L#32 (P#32)
                  PU L#33 (P#34)
                  PU L#34 (P#36)
                  PU L#35 (P#38)
          L3Cache L#9 (size=4096KB linesize=128 ways=16)
            L2Cache L#9 (size=1024KB linesize=128 ways=8)
              L1dCache L#9 (size=32KB linesize=128 ways=8)
                L1iCache L#9 (size=48KB linesize=128 ways=6)
                  PU L#36 (P#33)
                  PU L#37 (P#35)
                  PU L#38 (P#37)
                  PU L#39 (P#39)
  Group0 L#1 (total=7736896KB)
    Package L#2 (total=5170880KB CPUModel="POWER10 (architected), altivec supported" CPURevision="2.0 (pvr 0080 0200)")
      NUMANode L#2 (P#2 local=5170880KB total=5170880KB)
      Die L#4 (P#4)
<snipped>

Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20251112074859.814087-1-srikar@linux.ibm.com
arch/powerpc/include/asm/topology.h
arch/powerpc/kernel/smp.c

index f19ca44512d1e8bce5e3ced7d9666bf313a716c2..66ed5fe1b7184b2c1e3fa4e17de0a05cb0c3261a 100644 (file)
@@ -132,15 +132,18 @@ static inline int cpu_to_coregroup_id(int cpu)
 #include <asm/cputable.h>
 
 struct cpumask *cpu_coregroup_mask(int cpu);
+const struct cpumask *cpu_die_mask(int cpu);
+int cpu_die_id(int cpu);
 
 #ifdef CONFIG_PPC64
 #include <asm/smp.h>
 
 #define topology_physical_package_id(cpu)      (cpu_to_chip_id(cpu))
-
-#define topology_sibling_cpumask(cpu)  (per_cpu(cpu_sibling_map, cpu))
-#define topology_core_cpumask(cpu)     (per_cpu(cpu_core_map, cpu))
-#define topology_core_id(cpu)          (cpu_to_core_id(cpu))
+#define topology_sibling_cpumask(cpu)          (per_cpu(cpu_sibling_map, cpu))
+#define topology_core_cpumask(cpu)             (per_cpu(cpu_core_map, cpu))
+#define topology_core_id(cpu)                  (cpu_to_core_id(cpu))
+#define topology_die_id(cpu)                   (cpu_die_id(cpu))
+#define topology_die_cpumask(cpu)              (cpu_die_mask(cpu))
 
 #endif
 #endif
index 68edb66c2964baa5e44d5021b6581f613c19ab78..292fee8809bc8bbd6b8299a0ef70f3bbc72e24c3 100644 (file)
@@ -1085,6 +1085,29 @@ static int __init init_big_cores(void)
        return 0;
 }
 
+/*
+ * die_mask and die_id are only available on systems which support
+ * multiple coregroups within a same package. On all other systems, die_mask
+ * would be same as package mask and die_id would be set to -1.
+ */
+const struct cpumask *cpu_die_mask(int cpu)
+{
+       if (has_coregroup_support())
+               return per_cpu(cpu_coregroup_map, cpu);
+       else
+               return cpu_node_mask(cpu);
+}
+EXPORT_SYMBOL_GPL(cpu_die_mask);
+
+int cpu_die_id(int cpu)
+{
+       if (has_coregroup_support())
+               return cpu_to_coregroup_id(cpu);
+       else
+               return -1;
+}
+EXPORT_SYMBOL_GPL(cpu_die_id);
+
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        unsigned int cpu, num_threads;