]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/topo: Add topology_num_nodes_per_package()
authorPeter Zijlstra <peterz@infradead.org>
Tue, 3 Mar 2026 10:55:41 +0000 (11:55 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Wed, 4 Mar 2026 15:35:08 +0000 (16:35 +0100)
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
arch/x86/include/asm/topology.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/topology.c

index 1fadf0cf520c58cea9bb545b942e53bf20f565c3..0ba9bdb99871767a3bb1a4f27e3a9c9de35e28b9 100644 (file)
@@ -155,6 +155,7 @@ extern unsigned int __max_logical_packages;
 extern unsigned int __max_threads_per_core;
 extern unsigned int __num_threads_per_package;
 extern unsigned int __num_cores_per_package;
+extern unsigned int __num_nodes_per_package;
 
 const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);
 enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);
@@ -179,6 +180,11 @@ static inline unsigned int topology_num_threads_per_package(void)
        return __num_threads_per_package;
 }
 
+static inline unsigned int topology_num_nodes_per_package(void)
+{
+       return __num_nodes_per_package;
+}
+
 #ifdef CONFIG_X86_LOCAL_APIC
 int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);
 #else
index 1c3261cae40c9f5e8b3b0ed6de62d396a13c5570..a8ff4376c2860e20c5f65d3167d0c53fb876a87a 100644 (file)
@@ -95,6 +95,9 @@ EXPORT_SYMBOL(__max_dies_per_package);
 unsigned int __max_logical_packages __ro_after_init = 1;
 EXPORT_SYMBOL(__max_logical_packages);
 
+unsigned int __num_nodes_per_package __ro_after_init = 1;
+EXPORT_SYMBOL(__num_nodes_per_package);
+
 unsigned int __num_cores_per_package __ro_after_init = 1;
 EXPORT_SYMBOL(__num_cores_per_package);
 
index 23190a786d3104167beb0c2353d08bb2bf9e6aca..eafcb1fc185ad65565f93317248b2a13e8378a31 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mpspec.h>
 #include <asm/msr.h>
 #include <asm/smp.h>
+#include <asm/numa.h>
 
 #include "cpu.h"
 
@@ -492,11 +493,19 @@ void __init topology_init_possible_cpus(void)
        set_nr_cpu_ids(allowed);
 
        cnta = domain_weight(TOPO_PKG_DOMAIN);
-       cntb = domain_weight(TOPO_DIE_DOMAIN);
        __max_logical_packages = cnta;
+
+       pr_info("Max. logical packages: %3u\n", __max_logical_packages);
+
+       cntb = num_phys_nodes();
+       __num_nodes_per_package = DIV_ROUND_UP(cntb, cnta);
+
+       pr_info("Max. logical nodes:    %3u\n", cntb);
+       pr_info("Num. nodes per package:%3u\n", __num_nodes_per_package);
+
+       cntb = domain_weight(TOPO_DIE_DOMAIN);
        __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta));
 
-       pr_info("Max. logical packages: %3u\n", cnta);
        pr_info("Max. logical dies:     %3u\n", cntb);
        pr_info("Max. dies per package: %3u\n", __max_dies_per_package);