From e85ca71aadcc42a3f7cc90e6cff96c28f1c54290 Mon Sep 17 00:00:00 2001 From: attilio Date: Thu, 13 Aug 2009 17:09:45 +0000 Subject: * Completely Remove the option STOP_NMI from the kernel. This option has proven to have a good effect when entering KDB by using a NMI, but it completely violates all the good rules about interrupts disabled while holding a spinlock in other occasions. This can be the cause of deadlocks on events where a normal IPI_STOP is expected. * Adds an new IPI called IPI_STOP_HARD on all the supported architectures. This IPI is responsible for sending a stop message among CPUs using a privileged channel when disponible. In other cases it just does match a normal IPI_STOP. Right now the IPI_STOP_HARD functionality uses a NMI on ia32 and amd64 architectures, while on the other has a normal IPI_STOP effect. It is responsibility of maintainers to eventually implement an hard stop when necessary and possible. * Use the new IPI facility in order to implement a new userend SMP kernel function called stop_cpus_hard(). That is specular to stop_cpu() but it does use the privileged channel for the stopping facility. * Let KDB use the newly introduced function stop_cpus_hard() and leave stop_cpus() for all the other cases * Disable interrupts on CPU0 when starting the process of APs suspension. * Style cleanup and comments adding This patch should fix the reboot/shutdown deadlocks many users are constantly reporting on mailing lists. Please don't forget to update your config file with the STOP_NMI option removal Reviewed by: jhb Tested by: pho, bz, rink Approved by: re (kib) --- sys/powerpc/include/smp.h | 1 + sys/powerpc/powerpc/mp_machdep.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'sys/powerpc') diff --git a/sys/powerpc/include/smp.h b/sys/powerpc/include/smp.h index 3929b8c..0e5ec16 100644 --- a/sys/powerpc/include/smp.h +++ b/sys/powerpc/include/smp.h @@ -35,6 +35,7 @@ #define IPI_PREEMPT 1 #define IPI_RENDEZVOUS 2 #define IPI_STOP 3 +#define IPI_STOP_HARD 3 #ifndef LOCORE diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 2c6d11b..1ae7d6d 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -281,7 +281,13 @@ powerpc_ipi_handler(void *arg) smp_rendezvous_action(); break; case IPI_STOP: - CTR1(KTR_SMP, "%s: IPI_STOP (stop)", __func__); + + /* + * IPI_STOP_HARD is mapped to IPI_STOP so it is not + * necessary to add such case in the switch. + */ + CTR1(KTR_SMP, "%s: IPI_STOP or IPI_STOP_HARD (stop)", + __func__); self = PCPU_GET(cpumask); savectx(PCPU_GET(curpcb)); atomic_set_int(&stopped_cpus, self); -- cgit v1.1