MIPS: SMP_CPS: Switch to hotplug core state synchronization
authorThomas Gleixner <tglx@linutronix.de>
Fri, 12 May 2023 21:07:37 +0000 (23:07 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 15 May 2023 11:44:58 +0000 (13:44 +0200)
Switch to the CPU hotplug core state tracking and synchronization
mechanim. This unfortunately requires to add dead reporting to the non CPS
platforms as CPS is the only user, but it allows an overall consolidation
of this functionality.

No functional change intended.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Michael Kelley <mikelley@microsoft.com>
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Helge Deller <deller@gmx.de> # parisc
Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com> # Steam Deck
Link: https://lore.kernel.org/r/20230512205256.803238859@linutronix.de
arch/mips/Kconfig
arch/mips/cavium-octeon/smp.c
arch/mips/include/asm/smp-ops.h
arch/mips/kernel/smp-bmips.c
arch/mips/kernel/smp-cps.c
arch/mips/kernel/smp.c
arch/mips/loongson64/smp.c

index c2f5498d207fffd0f07bfff905ff75e05c504802..30e90a2d53f4a00163405ce8b85d2010c0c90caa 100644 (file)
@@ -2285,6 +2285,7 @@ config MIPS_CPS
        select MIPS_CM
        select MIPS_CPS_PM if HOTPLUG_CPU
        select SMP
+       select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
        select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
        select SYS_SUPPORTS_HOTPLUG_CPU
        select SYS_SUPPORTS_SCHED_SMT if CPU_MIPSR6
index 4212584e6efa9f255f25b71f642e8ad25df5c851..33c09688210fff313b48e438986b95da0f53be6c 100644 (file)
@@ -345,6 +345,7 @@ void play_dead(void)
        int cpu = cpu_number_map(cvmx_get_core_num());
 
        idle_task_exit();
+       cpuhp_ap_report_dead();
        octeon_processor_boot = 0xff;
        per_cpu(cpu_state, cpu) = CPU_DEAD;
 
index 0145bbfb5efb789fa9b085000359c1af1283ac0f..5719ff49eff1c88f0e3b44ee6f23287c6c4862e8 100644 (file)
@@ -33,6 +33,7 @@ struct plat_smp_ops {
 #ifdef CONFIG_HOTPLUG_CPU
        int (*cpu_disable)(void);
        void (*cpu_die)(unsigned int cpu);
+       void (*cleanup_dead_cpu)(unsigned cpu);
 #endif
 #ifdef CONFIG_KEXEC
        void (*kexec_nonboot_cpu)(void);
index 15466d4cf4a0e567256bb37afde1546ec46fb243..c074ecce3fbf29a313c1ddc9573967d21ce5d7e3 100644 (file)
@@ -392,6 +392,7 @@ static void bmips_cpu_die(unsigned int cpu)
 void __ref play_dead(void)
 {
        idle_task_exit();
+       cpuhp_ap_report_dead();
 
        /* flush data cache */
        _dma_cache_wback_inv(0, ~0);
index 62f677b2306ff31c33c357b140b3d2dec2154554..d7fdbec232daf371134ebf8641184669ce089970 100644 (file)
@@ -503,8 +503,7 @@ void play_dead(void)
                }
        }
 
-       /* This CPU has chosen its way out */
-       (void)cpu_report_death();
+       cpuhp_ap_report_dead();
 
        cps_shutdown_this_cpu(cpu_death);
 
@@ -527,7 +526,9 @@ static void wait_for_sibling_halt(void *ptr_cpu)
        } while (!(halted & TCHALT_H));
 }
 
-static void cps_cpu_die(unsigned int cpu)
+static void cps_cpu_die(unsigned int cpu) { }
+
+static void cps_cleanup_dead_cpu(unsigned cpu)
 {
        unsigned core = cpu_core(&cpu_data[cpu]);
        unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]);
@@ -535,12 +536,6 @@ static void cps_cpu_die(unsigned int cpu)
        unsigned stat;
        int err;
 
-       /* Wait for the cpu to choose its way out */
-       if (!cpu_wait_death(cpu, 5)) {
-               pr_err("CPU%u: didn't offline\n", cpu);
-               return;
-       }
-
        /*
         * Now wait for the CPU to actually offline. Without doing this that
         * offlining may race with one or more of:
@@ -624,6 +619,7 @@ static const struct plat_smp_ops cps_smp_ops = {
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_disable            = cps_cpu_disable,
        .cpu_die                = cps_cpu_die,
+       .cleanup_dead_cpu       = cps_cleanup_dead_cpu,
 #endif
 #ifdef CONFIG_KEXEC
        .kexec_nonboot_cpu      = cps_kexec_nonboot_cpu,
index 1d93b85271ba887a4dc0ea88ab9220b96f90265e..90c71d800b59eaf54fa089d422458bf9a00c744c 100644 (file)
@@ -690,6 +690,14 @@ void flush_tlb_one(unsigned long vaddr)
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(flush_tlb_one);
 
+#ifdef CONFIG_HOTPLUG_CORE_SYNC_DEAD
+void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu)
+{
+       if (mp_ops->cleanup_dead_cpu)
+               mp_ops->cleanup_dead_cpu(cpu);
+}
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 
 static void tick_broadcast_callee(void *info)
index b0e8bb9fa036fd7b4b9c800fd8f2996f4ae48950..cdecd7af11a6a0d8fe87f2c15c6e917148a5e97a 100644 (file)
@@ -775,6 +775,7 @@ void play_dead(void)
        void (*play_dead_at_ckseg1)(int *);
 
        idle_task_exit();
+       cpuhp_ap_report_dead();
 
        prid_imp = read_c0_prid() & PRID_IMP_MASK;
        prid_rev = read_c0_prid() & PRID_REV_MASK;