[RFC PATCH v3 08/13] sparc64: Initialize sbm topology on multi-LLC system
From: K Prateek Nayak
Date: Thu Oct 01 2026 - 15:33:28 EST
Once the CPU topology is parsed, initialize the sparsebitmap (sbm)
topology by counting the number of LLC / NUMA instances in the system
and the maximum number of threads in these instance.
Similar to alloc_irqstack_bootmem(), init_sbm_topology() is done after
setup_arch() has finished mapping the cache, socket, and NUMA IDs for
all the present CPUs.
arch_sbm_cpu_instance_id() uses a combination of cpu_to_node() and
max_cache_id to determine the sparsemask instances.
Signed-off-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>
---
Tested with sparc64_defconfig with
qemu-system-sparc64 \
-M sun4u \
-m 512 \
-kernel vmlinux \
-nographic -append "console=ttyS0"
Similar to some of my previous attempts, I was not able to boot a SMP
configuration with qemu-system-sparc64. For all purposes, sbm
initialization is only build tested.
---
arch/sparc/kernel/setup_64.c | 45 ++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 63615f5c99b4..7ab52d17e46f 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -28,6 +28,7 @@
#include <linux/root_dev.h>
#include <linux/interrupt.h>
#include <linux/cpu.h>
+#include <linux/sbm.h>
#include <linux/initrd.h>
#include <linux/module.h>
#include <linux/start_kernel.h>
@@ -53,6 +54,7 @@
#include <asm/cacheflush.h>
#include <asm/dma.h>
#include <asm/irq.h>
+#include <asm/cpudata.h>
#ifdef CONFIG_IP_PNP
#include <net/ipconfig.h>
@@ -619,6 +621,48 @@ static void __init alloc_irqstack_bootmem(void)
}
}
+static struct cpumask cpu_sbm_setup_map __initdata;
+static int __node_thread_count[NR_CPUS] __initdata;
+
+int arch_sbm_cpu_instance_id(int cpu)
+{
+ /* Combine the node and cache identifier. */
+ return ((u32)cpu_to_node(cpu) << 16) |
+ cpu_data(cpu).max_cache_id;
+}
+
+static void __init init_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) &&
+ cpu_data(i).max_cache_id == cpu_data(j).max_cache_id) {
+ 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);
+}
+
void __init setup_arch(char **cmdline_p)
{
/* Initialize PROM console and command line. */
@@ -677,6 +721,7 @@ void __init setup_arch(char **cmdline_p)
* allocate the IRQ stacks.
*/
alloc_irqstack_bootmem();
+ init_sbm_topology();
}
extern int stop_a_enabled;
--
2.34.1