Re: [RFC][PATCH 5/6] x86/topo: Fix SNC topology mess

From: Tim Chen

Date: Fri Feb 27 2026 - 14:25:23 EST


On Fri, 2026-02-27 at 14:01 +0100, Peter Zijlstra wrote:
> On Thu, Feb 26, 2026 at 11:00:38AM -0800, Tim Chen wrote:
> > May be a good idea to sanity check that the nodes in the first unit cluster
> > has the same package id and give a WARNING if that's not the case.
>
> But then we'd also have check the second cluster is another package. And
> if we're checking that, we might as well check they're symmetric.
>
> Is this sufficiently paranoid for you? :-)
>

Thanks. Looks pretty good and hopefully those warnings will
never be triggered.

Tim

>
> ---
> --- a/arch/x86/kernel/smpboot.c
> +++ b/arch/x86/kernel/smpboot.c
> @@ -61,6 +61,7 @@
> #include <linux/cpuhotplug.h>
> #include <linux/mc146818rtc.h>
> #include <linux/acpi.h>
> +#include <linux/once_lite.h>
>
> #include <asm/acpi.h>
> #include <asm/cacheinfo.h>
> @@ -506,12 +507,58 @@ static void __init build_sched_topology(
> }
>
> #ifdef CONFIG_NUMA
> +static bool slit_cluster_symmetric(int N)
> +{
> + for (int k = 0; k < __num_nodes_per_package; k++) {
> + for (int l = k; l < __num_nodes_per_package; l++) {
> + if (node_distance(N + k, N + l) !=
> + node_distance(N + l, N + k))
> + return false;
> + }
> + }
> +
> + return true;
> +}
> +
> +static u32 slit_cluster_package(int N)
> +{
> + u32 pkg_id = ~0;
> +
> + for (int n = 0; n < __num_nodes_per_package; n++) {
> + const struct cpumask *cpus = cpumask_of_node(N + n);
> + int cpu;
> +
> + for_each_cpu(cpu, cpus) {
> + u32 id = topology_logical_package_id(cpu);
> + if (pkg_id == ~0)
> + pkg_id = id;
> + if (pkg_id != id)
> + return ~0;
> + }
> + }
> +
> + return pkg_id;
> +}
> +
> +/* If you NUMA_EMU on top of SNC, you get to keep the pieces */
> +static void slit_validate(void)
> +{
> + u32 pkg1 = slit_cluster_package(0);
> + u32 pkg2 = slit_cluster_package(__num_nodes_per_package);
> + WARN_ON(pkg1 == ~0 || pkg2 == ~0 || pkg1 == pkg2);
> +
> + WARN_ON(!slit_cluster_symmetric(0));
> + WARN_ON(!slit_cluster_symmetric(__num_nodes_per_package));
> +}
> +
> static int slit_cluster_distance(int i, int j)
> {
> int u = __num_nodes_per_package;
> long d = 0;
> int x, y;
>
> + DO_ONCE_LITE(slit_validate);
> +
> /*
> * Is this a unit cluster on the trace?
> */
>