Skip to content

Commit edc0a2b

Browse files
zhang-ruihansendc
authored andcommitted
x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms
Traditionally, all CPUs in a system have identical numbers of SMT siblings. That changes with hybrid processors where some logical CPUs have a sibling and others have none. Today, the CPU boot code sets the global variable smp_num_siblings when every CPU thread is brought up. The last thread to boot will overwrite it with the number of siblings of *that* thread. That last thread to boot will "win". If the thread is a Pcore, smp_num_siblings == 2. If it is an Ecore, smp_num_siblings == 1. smp_num_siblings describes if the *system* supports SMT. It should specify the maximum number of SMT threads among all cores. Ensure that smp_num_siblings represents the system-wide maximum number of siblings by always increasing its value. Never allow it to decrease. On MeteorLake-P platform, this fixes a problem that the Ecore CPUs are not updated in any cpu sibling map because the system is treated as an UP system when probing Ecore CPUs. Below shows part of the CPU topology information before and after the fix, for both Pcore and Ecore CPU (cpu0 is Pcore, cpu 12 is Ecore). ... -/sys/devices/system/cpu/cpu0/topology/package_cpus:000fff -/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-11 +/sys/devices/system/cpu/cpu0/topology/package_cpus:3fffff +/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-21 ... -/sys/devices/system/cpu/cpu12/topology/package_cpus:001000 -/sys/devices/system/cpu/cpu12/topology/package_cpus_list:12 +/sys/devices/system/cpu/cpu12/topology/package_cpus:3fffff +/sys/devices/system/cpu/cpu12/topology/package_cpus_list:0-21 Notice that the "before" 'package_cpus_list' has only one CPU. This means that userspace tools like lscpu will see a little laptop like an 11-socket system: -Core(s) per socket: 1 -Socket(s): 11 +Core(s) per socket: 16 +Socket(s): 1 This is also expected to make the scheduler do rather wonky things too. [ dhansen: remove CPUID detail from changelog, add end user effects ] CC: [email protected] Fixes: bbb65d2 ("x86: use cpuid vector 0xb when available for detecting cpu topology") Fixes: 95f3d39 ("x86/cpu/topology: Provide detect_extended_topology_early()") Suggested-by: Len Brown <[email protected]> Signed-off-by: Zhang Rui <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/all/20230323015640.27906-1-rui.zhang%40intel.com
1 parent ce0b15d commit edc0a2b

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

arch/x86/kernel/cpu/topology.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c)
7979
* initial apic id, which also represents 32-bit extended x2apic id.
8080
*/
8181
c->initial_apicid = edx;
82-
smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
82+
smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
8383
#endif
8484
return 0;
8585
}
@@ -109,7 +109,8 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
109109
*/
110110
cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
111111
c->initial_apicid = edx;
112-
core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
112+
core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
113+
smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
113114
core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
114115
die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
115116
pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);

0 commit comments

Comments
 (0)