[RFC PATCH v3.1 04/13] LoongArch: Configure sbm topology during SMP preparation
flat view
WARM3d
From: K Prateek Nayak <kprateek.nayak@amd.com>
Date: 2026-10-07 03:52:10
Also in:
driver-core, linux-arch, linux-mips, linux-s390, lkml, loongarch
Subsystem:
loongarch, the rest · Maintainers:
Huacai Chen, Linus Torvalds
Revision v3 of 2 in this series.
Revisions (2)
- v3
- v3 current
Configure the sparsebitmask (sbm) topology for multi-node processors once SRAT is parsed and early_cpu_to_node() mappings are stable. The _PXM mappings are not reliable for disabled CPUs, and the worst case scenario is considered where the disabled CPUs can either form their own NUMA node (increases num_instances) or joins the node with the largest CPU count (increases max_cpus_per_instance). Since the final topology cannot be predicted at boot time, both are incremented with the count of disabled CPUs to account for topology going either ways. The sbm core will limit traversals to the nodes that are onlined and it is acceptable to overshoot the final limits. Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com> --- Changelog rfc v3 .. rfc v3.1: o Alternate scheme to use disabled CPUs to find the worst case topology instead of relying of incorrect changes to SRAT parsing. This was cross-compiled and tested on QEMU with: qemu-system-loongarch64 \ -machine virt \ -m 4G \ -cpu la464 \ -smp sockets=2,cores=8 \ -bios QEMU_EFI.fd \ -kernel arch/loongarch/boot/vmlinuz.efi \ -initrd ramdisk \ -serial stdio \ -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \ -object memory-backend-ram,size=2G,id=mem0 \ -object memory-backend-ram,size=2G,id=mem1 \ -numa node,nodeid=0,memdev=mem0,cpus=0-7 \ -numa node,nodeid=1,memdev=mem1,cpus=8-15 ... The incorrect SRAT parsing changes from v3 Patch 03/13 is no longer required with this alternate fallback. --- arch/loongarch/kernel/smp.c | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index d4b5d1b6bb01..6cf1f5ada038 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c@@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/irq_work.h> #include <linux/profile.h> +#include <linux/sbm.h> #include <linux/seq_file.h> #include <linux/smp.h> #include <linux/threads.h>
@@ -73,6 +74,10 @@ static cpumask_t cpu_llc_shared_setup_map; /* representing cpus for which core maps can be computed */ static cpumask_t cpu_core_setup_map; +/* sbm setup data - only needed during init */ +static cpumask_t cpu_sbm_setup_map __initdata; +static int __node_thread_count[NR_CPUS] __initdata; + struct secondary_data cpuboot_data; static DEFINE_PER_CPU(int, cpu_state);
@@ -362,10 +367,17 @@ void __init loongson_smp_setup(void) pr_info("Detected %i available CPU(s)\n", loongson_sysconf.nr_cpus); } +int arch_sbm_cpu_instance_id(int cpu) +{ + return cpu_to_node(cpu); +} + void __init loongson_prepare_cpus(unsigned int max_cpus) { int i = 0; + int disabled_cpus = 0; int threads_per_core = 0; + int num_sbm_instances, max_threads_per_instance = 1; parse_acpi_topology(); cpu_data[0].global_id = cpu_logical_map(0);
@@ -388,6 +400,46 @@ void __init loongson_prepare_cpus(unsigned int max_cpus) per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; cpu_smt_set_num_threads(threads_per_core, threads_per_core); + + for_each_possible_cpu(i) { + unsigned int node = early_cpu_to_node(i); + bool found = false; + int j; + + if (node == NUMA_NO_NODE) { + disabled_cpus++; + continue; + } + + for_each_cpu(j, &cpu_sbm_setup_map) { + if (node == early_cpu_to_node(j)) { + found = true; + break; + } + } + + if (!found) { + cpumask_set_cpu(i, &cpu_sbm_setup_map); + __node_thread_count[i] = 1; + continue; + } + + __node_thread_count[j] += 1; + max_threads_per_instance = max(max_threads_per_instance, + __node_thread_count[j]); + } + + /* + * In case of disabled CPUs, expect them to either show up as a + * new node or get added to the largest NUMA node. + * + * XXX: Is there a way to establish the correct CPU <-> node + * relation for CPUs that have disabled APIC? + */ + num_sbm_instances = cpumask_weight(&cpu_sbm_setup_map) + disabled_cpus; + max_threads_per_instance += disabled_cpus; + + sbm_set_topology(num_sbm_instances, max_threads_per_instance); } /*
--
2.34.1