e85ca71aad
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)
42 lines
881 B
C
42 lines
881 B
C
/*
|
|
* $FreeBSD$
|
|
*/
|
|
#ifndef _MACHINE_SMP_H_
|
|
#define _MACHINE_SMP_H_
|
|
|
|
#ifdef _KERNEL
|
|
|
|
/*
|
|
* Interprocessor interrupts for SMP. The following values are indices
|
|
* into the IPI vector table. The SAL gives us the vector used for AP
|
|
* wake-up. We base the other vectors on that. Keep IPI_AP_WAKEUP at
|
|
* index 0. See sal.c for details.
|
|
*/
|
|
/* Architecture specific IPIs. */
|
|
#define IPI_AP_WAKEUP 0
|
|
#define IPI_HIGH_FP 1
|
|
#define IPI_MCA_CMCV 2
|
|
#define IPI_MCA_RENDEZ 3
|
|
/* Machine independent IPIs. */
|
|
#define IPI_AST 4
|
|
#define IPI_RENDEZVOUS 5
|
|
#define IPI_STOP 6
|
|
#define IPI_STOP_HARD 6
|
|
#define IPI_PREEMPT 7
|
|
|
|
#define IPI_COUNT 8
|
|
|
|
#ifndef LOCORE
|
|
|
|
struct pcpu;
|
|
|
|
extern int ipi_vector[];
|
|
|
|
void ipi_all_but_self(int ipi);
|
|
void ipi_selected(cpumask_t cpus, int ipi);
|
|
void ipi_send(struct pcpu *, int ipi);
|
|
|
|
#endif /* !LOCORE */
|
|
#endif /* _KERNEL */
|
|
#endif /* !_MACHINE_SMP_H */
|