[PATCH] riscv: Populate boot CPU topology on UP kernels
Guo Ren
guoren at kernel.org
Wed Oct 14 01:47:39 PDT 2026
On Mon, Oct 12, 2026 at 9:11 PM Chen Pei <cp0613 at linux.alibaba.com> wrote:
>
> RISC-V selects GENERIC_ARCH_TOPOLOGY unconditionally, so the topology
> cpumask accessors resolve into cpu_topology[]. The RISC-V calls to
> init_cpu_topology() and store_cpu_topology() are in smpboot.c, which is
> only built with CONFIG_SMP. On UP kernels, cpu_topology[] remains
> zero-initialized and its sibling masks are empty.
>
> The sysfs topology interface is available on UP kernels too. As a
> result, cpu0 exports empty thread_siblings_list and core_siblings_list
> attributes rather than masks containing itself, violating the expected
> topology semantics of this stable ABI.
>
> Initialize and store the boot CPU topology in a UP-only early initcall.
> This runs after DT and ACPI CPU discovery and after the memory allocator
> is available, before the topology is exposed through sysfs.
>
> SMP kernels continue to initialize topology in smp_prepare_cpus(). NUMA
> needs no additional handling because it depends on SMP.
>
> Fixes: fbd92809997a ("riscv: topology: fix default topology reporting")
> Signed-off-by: Chen Pei <cp0613 at linux.alibaba.com>
> ---
> Tested on QEMU virt (RV64):
> - UP, default DT: cpu0 thread_siblings_list, core_cpus_list,
> core_siblings_list and package_cpus_list all contain CPU0.
> - UP, DT with 32 KiB L1 instruction/data caches: the same topology
> checks pass, and both caches appear in sysfs with shared_cpu_list=0.
> - SMP, 8 CPUs: each CPU's thread_siblings_list and core_cpus_list
> contain itself; core_siblings_list and package_cpus_list are 0-7.
>
> arch/riscv/kernel/setup.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index d79f99b86033..234d9af414b7 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -9,6 +9,7 @@
> */
>
> #include <linux/acpi.h>
> +#include <linux/arch_topology.h>
> #include <linux/cpu.h>
> #include <linux/init.h>
> #include <linux/mm.h>
> @@ -370,6 +371,17 @@ void __init setup_arch(char **cmdline_p)
> riscv_clear_hypervisor_csr();
> }
>
> +#ifndef CONFIG_SMP
> +static int __init riscv_init_cpu_topology(void)
> +{
> + init_cpu_topology();
> + store_cpu_topology(0);
> +
> + return 0;
> +}
> +early_initcall(riscv_init_cpu_topology);
> +#endif
> +
Good catch. Although CONFIG_SMP is enabled by default (default y), we
should still set the cpumask to BIT(0), so the cpumask stays valid
even when SMP is disabled.
Reviewed-by: GUO Ren <guoren at kernel.org>
--
Best Regards
Guo Ren
More information about the linux-riscv
mailing list