From 161f5a1189b78a61936dda31c7f864af6e0213e3 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 30 Mar 2024 10:57:45 +0100 Subject: [PATCH] sparc64: Fix number of online CPUs commit 98937707fea8375e8acea0aaa0b68a956dd52719 upstream. Nick Bowler reported: When using newer kernels on my Ultra 60 with dual 450MHz UltraSPARC-II CPUs, I noticed that only CPU 0 comes up, while older kernels (including 4.7) are working fine with both CPUs. I bisected the failure to this commit: 9b2f753ec23710aa32c0d837d2499db92fe9115b is the first bad commit commit 9b2f753ec23710aa32c0d837d2499db92fe9115b Author: Atish Patra Date: Thu Sep 15 14:54:40 2016 -0600 sparc64: Fix cpu_possible_mask if nr_cpus is set This is a small change that reverts very easily on top of 5.18: there is just one trivial conflict. Once reverted, both CPUs work again. Maybe this is related to the fact that the CPUs on this system are numbered CPU0 and CPU2 (there is no CPU1)? The current code that adjust cpu_possible based on nr_cpu_ids do not take into account that CPU's may not come one after each other. Move the chech to the function that setup the cpu_possible mask so there is no need to adjust it later. Signed-off-by: Sam Ravnborg Fixes: 9b2f753ec237 ("sparc64: Fix cpu_possible_mask if nr_cpus is set") Reported-by: Nick Bowler Tested-by: Nick Bowler Link: https://lore.kernel.org/sparclinux/20201009161924.c8f031c079dd852941307870@gmx.de/ Link: https://lore.kernel.org/all/CADyTPEwt=ZNams+1bpMB1F9w_vUdPsGCt92DBQxxq_VtaLoTdw@mail.gmail.com/ Cc: stable@vger.kernel.org # v4.8+ Cc: Andreas Larsson Cc: David S. Miller Cc: Atish Patra Cc: Bob Picco Cc: Vijay Kumar Cc: David S. Miller Reviewed-by: Andreas Larsson Acked-by: Arnd Bergmann Link: https://lore.kernel.org/r/20240330-sparc64-warnings-v1-9-37201023ee2f@ravnborg.org Signed-off-by: Andreas Larsson Signed-off-by: Greg Kroah-Hartman --- arch/sparc/include/asm/smp_64.h | 2 -- arch/sparc/kernel/prom_64.c | 4 +++- arch/sparc/kernel/setup_64.c | 1 - arch/sparc/kernel/smp_64.c | 14 -------------- 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index e75783b6abc4..16ab904616a0 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -47,7 +47,6 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask); int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu) -void smp_fill_in_cpu_possible_map(void); void smp_fill_in_sib_core_maps(void); void cpu_play_dead(void); @@ -77,7 +76,6 @@ void __cpu_die(unsigned int cpu); #define smp_fill_in_sib_core_maps() do { } while (0) #define smp_fetch_global_regs() do { } while (0) #define smp_fetch_global_pmu() do { } while (0) -#define smp_fill_in_cpu_possible_map() do { } while (0) #define smp_init_cpu_poke() do { } while (0) #define scheduler_poke() do { } while (0) diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index f883a50fa333..4eae633f7198 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -483,7 +483,9 @@ static void *record_one_cpu(struct device_node *dp, int cpuid, int arg) ncpus_probed++; #ifdef CONFIG_SMP set_cpu_present(cpuid, true); - set_cpu_possible(cpuid, true); + + if (num_possible_cpus() < nr_cpu_ids) + set_cpu_possible(cpuid, true); #endif return NULL; } diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index d87244197d5c..d921b4790af9 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -688,7 +688,6 @@ void __init setup_arch(char **cmdline_p) paging_init(); init_sparc64_elf_hwcap(); - smp_fill_in_cpu_possible_map(); /* * Once the OF device tree and MDESC have been setup and nr_cpus has * been parsed, we know the list of possible cpus. Therefore we can diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index ae5faa1d989d..748909095d9b 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1210,20 +1210,6 @@ void __init smp_setup_processor_id(void) xcall_deliver_impl = hypervisor_xcall_deliver; } -void __init smp_fill_in_cpu_possible_map(void) -{ - int possible_cpus = num_possible_cpus(); - int i; - - if (possible_cpus > nr_cpu_ids) - possible_cpus = nr_cpu_ids; - - for (i = 0; i < possible_cpus; i++) - set_cpu_possible(i, true); - for (; i < NR_CPUS; i++) - set_cpu_possible(i, false); -} - void smp_fill_in_sib_core_maps(void) { unsigned int i;