ARM: Stop secondary cpus in machine_halt()
PATCH 1/1 ARM: Stop secondary cpus in machine_halt()
ARM doesn't spin down secondary cpus on halt, which results in interrupts being delivered even after the "System halted" message, etc.
Change that to use smp_send_stop() to halt them. Also, change the smp_send_stop() on ARM to not do a stack dump when stopping.
--- arch/arm/kernel/process.c | 6 ++++++ arch/arm/kernel/smp.c | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-)
arch/arm/kernel/process.c +6 -0
@@ -191,6 +191,12 @@ __setup("reboot=", reboot_setup);void machine_halt (void ) { +#ifdef CONFIG_SMP +smp_send_stop (); +#endif +printk (KERN_EMERG "System halted, OK to turn off power\n" ); +local_irq_disable (); +while (1 ) ; }
arch/arm/kernel/smp.c +6 -4
@@ -467,10 +467,12 @@ static DEFINE_SPINLOCK(stop_lock);*/ static void ipi_cpu_stop (unsigned int cpu) { -spin_lock (&stop_lock); -printk (KERN_CRIT "CPU%u: stopping\n" , cpu); -dump_stack (); -spin_unlock (&stop_lock); +if (system_state !=SYSTEM_HALT ) { +spin_lock (&stop_lock); +printk (KERN_CRIT "CPU%u: stopping\n" , cpu); +dump_stack (); +spin_unlock (&stop_lock); + }set_cpu_online (cpu, false);
Signature · 1 line
1.5.6.5
PATCH 1/1 ARM: Stop secondary cpus in machine_halt()
Quoted 5 lines · Olof Johansson
ARM doesn't spin down secondary cpus on halt, which results in interrupts being delivered even after the "System halted" message, etc.
Change that to use
smp_send_stop()to halt them. Also, change thesmp_send_stop()on ARM to not do a stack dump when stopping.
Actually, we want stack dumps - sometimes. For instance, when we panic() or similar.
PATCH 1/1 ARM: Stop secondary cpus in machine_halt()
Quoted 9 lines · Russell King - ARM Linux
Quoted 5 lines · Olof Johansson
ARM doesn't spin down secondary cpus on halt, which results in interrupts being delivered even after the "System halted" message, etc.
Change that to use
smp_send_stop()to halt them. Also, change thesmp_send_stop()on ARM to not do a stack dump when stopping.Actually, we want stack dumps - sometimes. For instance, when we
panic()or similar.
Do we really want the stack dumps of all cpus at panic time? They won't be printed precisely since the IPI takes a while to make it over.
As the size of SMP systems grow, it'll also become too spammy.
Anyway, the patch only changes behaviour when the system_state is SYSTEM_HALT, i.e. during shutdown so all other panics will still dump stacks from all cpus.
-Olof
PATCH v2 1/1 ARM: Stop secondary cpus in machine_halt()
In reply to Olof JohanssonARM doesn't spin down secondary cpus on halt, which resulted interrupts being delivered even after the "System halted" message, etc.
Change that to use smp_send_stop() to halt them.
Also, change the smp_send_stop() on ARM to not do a stack dump when stopping the cpus during halt (but still print during other stops, i.e. panic).
--- arch/arm/kernel/process.c | 6 ++++++ arch/arm/kernel/smp.c | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-)
arch/arm/kernel/process.c +6 -0
@@ -191,6 +191,12 @@ __setup("reboot=", reboot_setup);void machine_halt (void ) { +#ifdef CONFIG_SMP +smp_send_stop (); +#endif +printk (KERN_EMERG "System halted, OK to turn off power\n" ); +local_irq_disable (); +while (1 ) ; }
arch/arm/kernel/smp.c +6 -4
@@ -467,10 +467,12 @@ static DEFINE_SPINLOCK(stop_lock);*/ static void ipi_cpu_stop (unsigned int cpu) { -spin_lock (&stop_lock); -printk (KERN_CRIT "CPU%u: stopping\n" , cpu); -dump_stack (); -spin_unlock (&stop_lock); +if (system_state !=SYSTEM_HALT ) { +spin_lock (&stop_lock); +printk (KERN_CRIT "CPU%u: stopping\n" , cpu); +dump_stack (); +spin_unlock (&stop_lock); + }set_cpu_online (cpu, false);
Signature · 1 line
1.5.6.5
PATCH v2 1/1 ARM: Stop secondary cpus in machine_halt()
Quoted 8 lines · Olof Johansson
ARM doesn't spin down secondary cpus on halt, which resulted interrupts being delivered even after the "System halted" message, etc.
Change that to use
smp_send_stop()to halt them.Also, change the
smp_send_stop()on ARM to not do a stack dump when stopping the cpus during halt (but still print during other stops, i.e. panic).
Hmm... what about kexec on a SMP system, or we try to reboot a SMP system?
The x86 code suggests that we put smp_send_stop() inside machine_shutdown() (and move that function into arch/arm/kernel/process.c) and call it from machine_halt() and machine_reboot().
This will cover the kexec and reboot cases too.
So, something like this:
arch/arm/kernel/machine_kexec.c +0 -4
@@ -37,10 +37,6 @@ void machine_kexec_cleanup(struct kimage *image) { } -void machine_shutdown (void ) -{ -} -void machine_crash_shutdown (struct pt_regs *regs) { }
arch/arm/kernel/process.c +11 -1
@@ -189,19 +189,29 @@ int __init reboot_setup(char *str)__setup ("reboot=" , reboot_setup); -void machine_halt (void ) +void machine_shutdown (void ) { +#ifdef CONFIG_SMP +smp_send_stop (); +#endif } +void machine_halt (void ) +{ +machine_shutdown (); +while (1 ); +}void machine_power_off (void ) { +machine_shutdown ();if (pm_power_off)pm_power_off (); }void machine_restart (char *cmd) { +machine_shutdown ();arm_pm_restart (reboot_mode, cmd); }
arch/arm/kernel/smp.c +7 -4
@@ -467,10 +467,13 @@ static DEFINE_SPINLOCK(stop_lock);*/ static void ipi_cpu_stop (unsigned int cpu) { -spin_lock (&stop_lock); -printk (KERN_CRIT "CPU%u: stopping\n" , cpu); -dump_stack (); -spin_unlock (&stop_lock); +if (system_state ==SYSTEM_BOOTING || + system_state ==SYSTEM_RUNNING ) { +spin_lock (&stop_lock); +printk (KERN_CRIT "CPU%u: stopping\n" , cpu); +dump_stack (); +spin_unlock (&stop_lock); + }set_cpu_online (cpu, false);
PATCH v2 1/1 ARM: Stop secondary cpus in machine_halt()
Quoted 8 lines · Russell King - ARM Linux
Hmm... what about kexec on a SMP system, or we try to reboot a SMP system?
The x86 code suggests that we put
smp_send_stop()insidemachine_shutdown()(and move that function intoarch/arm/kernel/process.c) and call it frommachine_halt()andmachine_reboot().This will cover the kexec and reboot cases too.
As no one's commented on this, I'm going to apply it later today for the next merge window - it seems to be the right way to solve this problem, and makes us reflect what x86 does.
Quoted 79 lines
So, something like this:
arch/arm/kernel/machine_kexec.c +0
-4@@ -37,10 +37,6 @@ void machine_kexec_cleanup(struct kimage *image) { } -void machine_shutdown (void ) -{ -} -void machine_crash_shutdown (struct pt_regs *regs) { }arch/arm/kernel/process.c +11
-1@@ -189,19 +189,29 @@ int __init reboot_setup(char *str)__setup ("reboot=" , reboot_setup); -void machine_halt (void ) +void machine_shutdown (void ) { +#ifdef CONFIG_SMP +smp_send_stop (); +#endif } +void machine_halt (void ) +{ +machine_shutdown (); +while (1 ); +}void machine_power_off (void ) { +machine_shutdown ();if (pm_power_off)pm_power_off (); }void machine_restart (char *cmd) { +machine_shutdown ();arm_pm_restart (reboot_mode, cmd); }arch/arm/kernel/smp.c +7
-4@@ -467,10 +467,13 @@ static DEFINE_SPINLOCK(stop_lock);*/ static void ipi_cpu_stop (unsigned int cpu) { -spin_lock (&stop_lock); -printk (KERN_CRIT "CPU%u: stopping\n" , cpu); -dump_stack (); -spin_unlock (&stop_lock); +if (system_state ==SYSTEM_BOOTING || + system_state ==SYSTEM_RUNNING ) { +spin_lock (&stop_lock); +printk (KERN_CRIT "CPU%u: stopping\n" , cpu); +dump_stack (); +spin_unlock (&stop_lock); + }set_cpu_online (cpu, false);_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 1/1 ARM: Stop secondary cpus in machine_halt()
Quoted 8 lines · Russell King - ARM Linux
Quoted 7 lines · Russell King - ARM Linux
Hmm... what about kexec on a SMP system, or we try to reboot a SMP system?
The x86 code suggests that we put
smp_send_stop()insidemachine_shutdown()(and move that function intoarch/arm/kernel/process.c) and call it frommachine_halt()andmachine_reboot().
Quoted 5 lines
Quoted 1 line
This will cover the kexec and reboot cases too.
As no one's commented on this, I'm going to apply it later today for the next merge window - it seems to be the right way to solve this problem, and makes us reflect what x86 does.
Yeah, looks good to me.
-Olof