For MIPS systems that support NUMA, configure the sparsebitmap (sbm) topology.
The two systems that toggle NUMA - loongson64 and sgi-ip27, find the number of nodes and the maximum threads present in an instance. The data structures used to parse the topology are marked __initdata to allow reclaim post init. In both cases - loongson64 and sgi-ip27, loongson3_smp_setup() and node_scan_cpus() sets node IDs for all possible CPUs ensuring configure_sbm_topology() captures the full possible system. arch_sbm_cpu_instance_id() returns the cpu_to_node() mapping to derive the instance ID and group the CPUs sharing the node on the same sbm instance (leaf). Signed-off-by: K Prateek Nayak <[email protected]> --- Tested on QEMU with loongson3_defconfig from https://gitlab.postmarketos.org/royka1/linux/-/blob/apollo-7.1.0-r3/arch/mips/configs/loongson3_defconfig?ref_type=tags QEMU cmdline: qemu-system-mips64el \ -M loongson3-virt,accel=tcg \ -smp sockets=2,cores=4 \ -cpu Loongson-3A1000 \ -kernel vmlinux \ -append "console=ttyS0 root=/dev/ram" \ -nographic --- arch/mips/include/asm/topology.h | 6 +++++ arch/mips/kernel/topology.c | 43 ++++++++++++++++++++++++++++++++ arch/mips/loongson64/smp.c | 3 +++ arch/mips/sgi-ip27/ip27-smp.c | 3 +++ 4 files changed, 55 insertions(+) diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h index 5158c802eb65..7a57cbd59819 100644 --- a/arch/mips/include/asm/topology.h +++ b/arch/mips/include/asm/topology.h @@ -21,4 +21,10 @@ extern struct cpumask __cpu_primary_thread_mask; #define cpu_primary_thread_mask ((const struct cpumask *)&__cpu_primary_thread_mask) #endif +#ifdef CONFIG_NUMA +extern void configure_sbm_topology(void); +#else /* !CONFIG_NUMA */ +static void __maybe_unused configure_sbm_topology(void) { } +#endif /* CONFIG_NUMA */ + #endif /* __ASM_TOPOLOGY_H */ diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c index 9429d85a4703..729a811e8b99 100644 --- a/arch/mips/kernel/topology.c +++ b/arch/mips/kernel/topology.c @@ -5,9 +5,52 @@ #include <linux/node.h> #include <linux/nodemask.h> #include <linux/percpu.h> +#include <linux/sbm.h> static DEFINE_PER_CPU(struct cpu, cpu_devices); +#ifdef CONFIG_NUMA +/* sbm setup data - only needed during init */ +static struct cpumask cpu_sbm_setup_map __initdata; +static int __node_thread_count[NR_CPUS] __initdata; + +int arch_sbm_cpu_instance_id(int cpu) +{ + return cpu_to_node(cpu); +} + +void __init configure_sbm_topology(void) +{ + int num_sbm_instances, max_threads_per_instance = 1; + int i; + + for_each_possible_cpu(i) { + bool found = false; + int j; + + for_each_cpu(j, &cpu_sbm_setup_map) { + if (cpu_to_node(i) == 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]); + } + + num_sbm_instances = cpumask_weight(&cpu_sbm_setup_map); + sbm_set_topology(num_sbm_instances, max_threads_per_instance); +} +#endif /* CONFIG_NUMA */ + static int __init topology_init(void) { int i, ret; diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c index e584299d0fde..22174ae2b574 100644 --- a/arch/mips/loongson64/smp.c +++ b/arch/mips/loongson64/smp.c @@ -17,6 +17,7 @@ #include <asm/smp.h> #include <asm/time.h> #include <asm/tlbflush.h> +#include <asm/topology.h> #include <asm/cacheflush.h> #include <loongson.h> #include <loongson_regs.h> @@ -493,6 +494,8 @@ static void __init loongson3_smp_setup(void) if (smp_group[0]) ipi_write_enable(0); + configure_sbm_topology(); + cpu_set_core(&cpu_data[0], cpu_logical_map(0) % loongson_sysconf.cores_per_package); cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index 62733e049570..244f8d987f13 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c @@ -15,6 +15,7 @@ #include <asm/page.h> #include <asm/processor.h> #include <asm/ptrace.h> +#include <asm/topology.h> #include <asm/sn/agent.h> #include <asm/sn/arch.h> #include <asm/sn/gda.h> @@ -80,6 +81,8 @@ void cpu_node_probe(void) highest = node_scan_cpus(nasid, highest); } + configure_sbm_topology(); + printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes()); } -- 2.34.1
