No subject


Tue Oct 28 22:00:03 AEDT 2025


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/cpu8/topology/{die*,package*} 2> /dev/null
/sys/devices/system/cpu/cpu8/topology/package_cpus:0000,ffffff00
/sys/devices/system/cpu/cpu8/topology/package_cpus_list:8-31

With this change.
$ grep . /sys/devices/system/cpu/cpu8/topology/{die*,package*} 2> /dev/null
/sys/devices/system/cpu/cpu8/topology/die_cpus:0000,0000ff00
/sys/devices/system/cpu/cpu8/topology/die_cpus_list:8-15
/sys/devices/system/cpu/cpu8/topology/die_id:4
/sys/devices/system/cpu/cpu8/topology/package_cpus:0000,ffffff00
/sys/devices/system/cpu/cpu8/topology/package_cpus_list:8-31

snipped lstopo-no-graphics o/p
Group0 L#0
  Package L#1
    NUMANode L#1 (P#2 8135MB)
    Die L#0 + Core L#1
      L3 L#2 (4096KB) + L2 L#2 (1024KB) + L1d L#2 (32KB) + L1i L#2 (48KB)
        PU L#8 (P#8)
        PU L#9 (P#10)
        PU L#10 (P#12)
        PU L#11 (P#14)
      L3 L#3 (4096KB) + L2 L#3 (1024KB) + L1d L#3 (32KB) + L1i L#3 (48KB)
        PU L#12 (P#9)
        PU L#13 (P#11)
        PU L#14 (P#13)
        PU L#15 (P#15)
    Die L#1
      Core L#2
        L3 L#4 (4096KB) + L2 L#4 (1024KB) + L1d L#4 (32KB) + L1i L#4 (48KB)
          PU L#16 (P#16)
          PU L#17 (P#18)
          PU L#18 (P#20)
          PU L#19 (P#22)
        L3 L#5 (4096KB) + L2 L#5 (1024KB) + L1d L#5 (32KB) + L1i L#5 (48KB)
          PU L#20 (P#17)
          PU L#21 (P#19)
          PU L#22 (P#21)
          PU L#23 (P#23)
      Core L#3
        L3 L#6 (4096KB) + L2 L#6 (1024KB) + L1d L#6 (32KB) + L1i L#6 (48KB)
          PU L#24 (P#24)
          PU L#25 (P#26)
          PU L#26 (P#28)
          PU L#27 (P#30)
        L3 L#7 (4096KB) + L2 L#7 (1024KB) + L1d L#7 (32KB) + L1i L#7 (48KB)
          PU L#28 (P#25)
          PU L#29 (P#27)
          PU L#30 (P#29)
          PU L#31 (P#31)
  Package L#2

Signed-off-by: Srikar Dronamraju <srikar at linux.ibm.com>
---
 arch/powerpc/include/asm/topology.h |  4 ++++
 arch/powerpc/kernel/smp.c           | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index f19ca44512d1..c6ad1eb7e44a 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -132,6 +132,8 @@ 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>
@@ -141,6 +143,8 @@ struct cpumask *cpu_coregroup_mask(int 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
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 68edb66c2964..a0b0b46b78e3 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -1085,6 +1085,24 @@ static int __init init_big_cores(void)
 	return 0;
 }
 
+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;
-- 
2.43.5



More information about the Linuxppc-dev mailing list