Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/topo: Add topology_num_nodes_per_package()

Use the MADT and SRAT table data to compute __num_nodes_per_package.

Specifically, SRAT has already been parsed in x86_numa_init(), which is called
before acpi_boot_init() which parses MADT. So both are available in
topology_init_possible_cpus().

This number is useful to divinate the various Intel CoD/SNC and AMD NPS modes,
since the platforms are failing to provide this otherwise.

Doing it this way is independent of the number of online CPUs and
other such shenanigans.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Tony Luck <tony.luck@intel.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Chen Yu <yu.c.chen@intel.com>
Tested-by: Kyle Meyer <kyle.meyer@hpe.com>
Link: https://patch.msgid.link/20260303110100.004091624@infradead.org

+20 -2
+6
arch/x86/include/asm/topology.h
··· 155 155 extern unsigned int __max_threads_per_core; 156 156 extern unsigned int __num_threads_per_package; 157 157 extern unsigned int __num_cores_per_package; 158 + extern unsigned int __num_nodes_per_package; 158 159 159 160 const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); 160 161 enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); ··· 178 177 static inline unsigned int topology_num_threads_per_package(void) 179 178 { 180 179 return __num_threads_per_package; 180 + } 181 + 182 + static inline unsigned int topology_num_nodes_per_package(void) 183 + { 184 + return __num_nodes_per_package; 181 185 } 182 186 183 187 #ifdef CONFIG_X86_LOCAL_APIC
+3
arch/x86/kernel/cpu/common.c
··· 95 95 unsigned int __max_logical_packages __ro_after_init = 1; 96 96 EXPORT_SYMBOL(__max_logical_packages); 97 97 98 + unsigned int __num_nodes_per_package __ro_after_init = 1; 99 + EXPORT_SYMBOL(__num_nodes_per_package); 100 + 98 101 unsigned int __num_cores_per_package __ro_after_init = 1; 99 102 EXPORT_SYMBOL(__num_cores_per_package); 100 103
+11 -2
arch/x86/kernel/cpu/topology.c
··· 31 31 #include <asm/mpspec.h> 32 32 #include <asm/msr.h> 33 33 #include <asm/smp.h> 34 + #include <asm/numa.h> 34 35 35 36 #include "cpu.h" 36 37 ··· 493 492 set_nr_cpu_ids(allowed); 494 493 495 494 cnta = domain_weight(TOPO_PKG_DOMAIN); 496 - cntb = domain_weight(TOPO_DIE_DOMAIN); 497 495 __max_logical_packages = cnta; 496 + 497 + pr_info("Max. logical packages: %3u\n", __max_logical_packages); 498 + 499 + cntb = num_phys_nodes(); 500 + __num_nodes_per_package = DIV_ROUND_UP(cntb, cnta); 501 + 502 + pr_info("Max. logical nodes: %3u\n", cntb); 503 + pr_info("Num. nodes per package:%3u\n", __num_nodes_per_package); 504 + 505 + cntb = domain_weight(TOPO_DIE_DOMAIN); 498 506 __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta)); 499 507 500 - pr_info("Max. logical packages: %3u\n", cnta); 501 508 pr_info("Max. logical dies: %3u\n", cntb); 502 509 pr_info("Max. dies per package: %3u\n", __max_dies_per_package); 503 510