diff options
| author | Tor Egge <tegge@FreeBSD.org> | 1998-03-03 20:55:26 +0000 |
|---|---|---|
| committer | Tor Egge <tegge@FreeBSD.org> | 1998-03-03 20:55:26 +0000 |
| commit | 3163861c7bb17056051e94ed6a8e34108a4d7ce0 (patch) | |
| tree | d39f111e4c67aa276feecb7cb8b2ff7a7c676367 /sys | |
| parent | fe9cd27373ba2d41a792f8857ed4dd9205a29f88 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/amd64/amd64/apic_vector.S | 10 | ||||
| -rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 56 | ||||
| -rw-r--r-- | sys/amd64/amd64/mptable.c | 56 | ||||
| -rw-r--r-- | sys/amd64/include/mptable.h | 56 | ||||
| -rw-r--r-- | sys/amd64/include/smp.h | 5 | ||||
| -rw-r--r-- | sys/amd64/isa/intr_machdep.h | 8 | ||||
| -rw-r--r-- | sys/i386/i386/apic_vector.s | 10 | ||||
| -rw-r--r-- | sys/i386/i386/mp_machdep.c | 56 | ||||
| -rw-r--r-- | sys/i386/i386/mptable.c | 56 | ||||
| -rw-r--r-- | sys/i386/include/mptable.h | 56 | ||||
| -rw-r--r-- | sys/i386/include/smp.h | 5 | ||||
| -rw-r--r-- | sys/i386/isa/apic_vector.s | 10 | ||||
| -rw-r--r-- | sys/i386/isa/intr_machdep.h | 8 | ||||
| -rw-r--r-- | sys/kern/kern_sig.c | 9 | ||||
| -rw-r--r-- | sys/kern/subr_smp.c | 56 | ||||
| -rw-r--r-- | sys/sys/smp.h | 5 |
16 files changed, 417 insertions, 45 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index a98ef4668e85..460344097e4b 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.24 1997/12/08 22:59:34 fsmp Exp $ + * $Id: apic_vector.s,v 1.25 1998/01/15 07:33:58 gibbs Exp $ */ @@ -472,6 +472,8 @@ _Xcpucheckstate: popl %eax iret +#endif /* BETTER_CLOCK */ + /* * Executed by a CPU when it receives an Xcpuast IPI from another CPU, * @@ -534,8 +536,6 @@ _Xcpuast: POP_FRAME iret -#endif /* BETTER_CLOCK */ - /* * Executed by a CPU when it receives an Xcpustop IPI from another CPU, @@ -694,14 +694,14 @@ _started_cpus: #ifdef BETTER_CLOCK .globl _checkstate_probed_cpus - .globl _checkstate_need_ast _checkstate_probed_cpus: .long 0 +#endif /* BETTER_CLOCK */ + .globl _checkstate_need_ast _checkstate_need_ast: .long 0 _checkstate_pending_ast: .long 0 -#endif .globl _apic_pin_trigger _apic_pin_trigger: diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index d059fa07c23e..82ae434e18e0 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index d059fa07c23e..82ae434e18e0 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index d059fa07c23e..82ae434e18e0 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 08fffbe3f58a..482b86015a2a 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.35 1998/02/25 03:56:15 dyson Exp $ + * $Id: smp.h,v 1.36 1998/03/03 19:44:34 tegge Exp $ * */ @@ -79,10 +79,8 @@ extern u_int ivectors[]; extern volatile u_int stopped_cpus; extern volatile u_int started_cpus; -#ifdef BETTER_CLOCK extern unsigned int checkstate_probed_cpus; extern unsigned int checkstate_need_ast; -#endif /* global data in apic_ipl.s */ extern u_int vec[]; @@ -138,6 +136,7 @@ int restart_cpus __P((u_int)); void forward_statclock __P((int pscnt)); void forward_hardclock __P((int pscnt)); #endif /* BETTER_CLOCK */ +void forward_signal __P((struct proc *)); /* global data in mpapic.c */ extern volatile lapic_t lapic; diff --git a/sys/amd64/isa/intr_machdep.h b/sys/amd64/isa/intr_machdep.h index fd0e9e7a6683..7714c0d7f1d4 100644 --- a/sys/amd64/isa/intr_machdep.h +++ b/sys/amd64/isa/intr_machdep.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91 - * $Id: intr_machdep.h,v 1.8 1997/12/08 22:59:39 fsmp Exp $ + * $Id: intr_machdep.h,v 1.9 1998/02/13 06:59:22 bde Exp $ */ #ifndef _I386_ISA_INTR_MACHDEP_H_ @@ -111,9 +111,11 @@ #ifdef BETTER_CLOCK /* inter-cpu clock handling */ #define XCPUCHECKSTATE_OFFSET (ICU_OFFSET + 113) -#define XCPUAST_OFFSET (ICU_OFFSET + 114) #endif +/* IPI to generate an additional software trap at the target CPU */ +#define XCPUAST_OFFSET (ICU_OFFSET + 48) + /* IPI to signal CPUs to stop and wait for another CPU to restart them */ #define XCPUSTOP_OFFSET (ICU_OFFSET + 128) @@ -170,8 +172,8 @@ inthand_t Xinvltlb, /* TLB shootdowns */ #ifdef BETTER_CLOCK Xcpucheckstate, /* Check cpu state */ - Xcpuast, /* Additional software trap on other cpu */ #endif + Xcpuast, /* Additional software trap on other cpu */ Xcpustop, /* CPU stops & waits for another CPU to restart it */ Xspuriousint; /* handle APIC "spurious INTs" */ diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index a98ef4668e85..460344097e4b 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.24 1997/12/08 22:59:34 fsmp Exp $ + * $Id: apic_vector.s,v 1.25 1998/01/15 07:33:58 gibbs Exp $ */ @@ -472,6 +472,8 @@ _Xcpucheckstate: popl %eax iret +#endif /* BETTER_CLOCK */ + /* * Executed by a CPU when it receives an Xcpuast IPI from another CPU, * @@ -534,8 +536,6 @@ _Xcpuast: POP_FRAME iret -#endif /* BETTER_CLOCK */ - /* * Executed by a CPU when it receives an Xcpustop IPI from another CPU, @@ -694,14 +694,14 @@ _started_cpus: #ifdef BETTER_CLOCK .globl _checkstate_probed_cpus - .globl _checkstate_need_ast _checkstate_probed_cpus: .long 0 +#endif /* BETTER_CLOCK */ + .globl _checkstate_need_ast _checkstate_need_ast: .long 0 _checkstate_pending_ast: .long 0 -#endif .globl _apic_pin_trigger _apic_pin_trigger: diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index d059fa07c23e..82ae434e18e0 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index d059fa07c23e..82ae434e18e0 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index d059fa07c23e..82ae434e18e0 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 08fffbe3f58a..482b86015a2a 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.35 1998/02/25 03:56:15 dyson Exp $ + * $Id: smp.h,v 1.36 1998/03/03 19:44:34 tegge Exp $ * */ @@ -79,10 +79,8 @@ extern u_int ivectors[]; extern volatile u_int stopped_cpus; extern volatile u_int started_cpus; -#ifdef BETTER_CLOCK extern unsigned int checkstate_probed_cpus; extern unsigned int checkstate_need_ast; -#endif /* global data in apic_ipl.s */ extern u_int vec[]; @@ -138,6 +136,7 @@ int restart_cpus __P((u_int)); void forward_statclock __P((int pscnt)); void forward_hardclock __P((int pscnt)); #endif /* BETTER_CLOCK */ +void forward_signal __P((struct proc *)); /* global data in mpapic.c */ extern volatile lapic_t lapic; diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index a98ef4668e85..460344097e4b 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.24 1997/12/08 22:59:34 fsmp Exp $ + * $Id: apic_vector.s,v 1.25 1998/01/15 07:33:58 gibbs Exp $ */ @@ -472,6 +472,8 @@ _Xcpucheckstate: popl %eax iret +#endif /* BETTER_CLOCK */ + /* * Executed by a CPU when it receives an Xcpuast IPI from another CPU, * @@ -534,8 +536,6 @@ _Xcpuast: POP_FRAME iret -#endif /* BETTER_CLOCK */ - /* * Executed by a CPU when it receives an Xcpustop IPI from another CPU, @@ -694,14 +694,14 @@ _started_cpus: #ifdef BETTER_CLOCK .globl _checkstate_probed_cpus - .globl _checkstate_need_ast _checkstate_probed_cpus: .long 0 +#endif /* BETTER_CLOCK */ + .globl _checkstate_need_ast _checkstate_need_ast: .long 0 _checkstate_pending_ast: .long 0 -#endif .globl _apic_pin_trigger _apic_pin_trigger: diff --git a/sys/i386/isa/intr_machdep.h b/sys/i386/isa/intr_machdep.h index fd0e9e7a6683..7714c0d7f1d4 100644 --- a/sys/i386/isa/intr_machdep.h +++ b/sys/i386/isa/intr_machdep.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91 - * $Id: intr_machdep.h,v 1.8 1997/12/08 22:59:39 fsmp Exp $ + * $Id: intr_machdep.h,v 1.9 1998/02/13 06:59:22 bde Exp $ */ #ifndef _I386_ISA_INTR_MACHDEP_H_ @@ -111,9 +111,11 @@ #ifdef BETTER_CLOCK /* inter-cpu clock handling */ #define XCPUCHECKSTATE_OFFSET (ICU_OFFSET + 113) -#define XCPUAST_OFFSET (ICU_OFFSET + 114) #endif +/* IPI to generate an additional software trap at the target CPU */ +#define XCPUAST_OFFSET (ICU_OFFSET + 48) + /* IPI to signal CPUs to stop and wait for another CPU to restart them */ #define XCPUSTOP_OFFSET (ICU_OFFSET + 128) @@ -170,8 +172,8 @@ inthand_t Xinvltlb, /* TLB shootdowns */ #ifdef BETTER_CLOCK Xcpucheckstate, /* Check cpu state */ - Xcpuast, /* Additional software trap on other cpu */ #endif + Xcpuast, /* Additional software trap on other cpu */ Xcpustop, /* CPU stops & waits for another CPU to restart it */ Xspuriousint; /* handle APIC "spurious INTs" */ diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 0cb6f39664e9..d7f4dc31e2eb 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 - * $Id: kern_sig.c,v 1.38 1998/02/04 22:32:33 eivind Exp $ + * $Id: kern_sig.c,v 1.39 1998/02/06 12:13:24 eivind Exp $ */ #include "opt_compat.h" @@ -61,6 +61,9 @@ #include <sys/sysent.h> #include <machine/cpu.h> +#ifdef SMP +#include <machine/smp.h> +#endif /* All these for coredump() only. */ #include <vm/vm.h> @@ -919,6 +922,10 @@ psignal(p, signum) */ if (p == curproc) signotify(p); +#ifdef SMP + else if (p->p_stat == SRUN) + forward_signal(p); +#endif goto out; } /*NOTREACHED*/ diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index d059fa07c23e..82ae434e18e0 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.66 1998/03/01 04:18:50 dyson Exp $ + * $Id: mp_machdep.c,v 1.67 1998/03/03 20:09:14 tegge Exp $ */ #include "opt_smp.h" @@ -569,11 +569,11 @@ mp_enable(u_int boot_addr) /* install an inter-CPU IPI for reading processor state */ setidt(XCPUCHECKSTATE_OFFSET, Xcpucheckstate, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* install an inter-CPU IPI for forcing an additional software trap */ setidt(XCPUAST_OFFSET, Xcpuast, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); -#endif /* install an inter-CPU IPI for CPU stop/restart */ setidt(XCPUSTOP_OFFSET, Xcpustop, @@ -1995,6 +1995,10 @@ int do_page_zero_idle = 1; /* bzero pages for fun and profit in idleloop */ SYSCTL_INT(_machdep, OID_AUTO, do_page_zero_idle, CTLFLAG_RW, &do_page_zero_idle, 0, ""); +/* Enable forwarding of a signal to a process running on a different CPU */ +int forward_signal_enabled = 1; +SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW, + &forward_signal_enabled, 0, ""); /* * This is called once the rest of the system is up and running and we're @@ -2386,3 +2390,51 @@ forward_hardclock(int pscnt) } #endif /* BETTER_CLOCK */ + +void +forward_signal(struct proc *p) +{ + int map; + int id; + int i; + + /* Kludge. We don't yet have separate locks for the interrupts + * and the kernel. This means that we cannot let the other processors + * handle complex interrupts while inhibiting them from entering + * the kernel in a non-interrupt context. + * + * What we can do, without changing the locking mechanisms yet, + * is letting the other processors handle a very simple interrupt + * (wich determines the processor states), and do the main + * work ourself. + */ + + if (!smp_started || !invltlb_ok || cold || panicstr) + return; + if (!forward_signal_enabled) + return; + while (1) { + if (p->p_stat != SRUN) + return; + id = (u_char) p->p_oncpu; + if (id == 0xff) + return; + map = (1<<id); + checkstate_need_ast |= map; + selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); + i = 0; + while ((checkstate_need_ast & map) != 0) { + /* spin */ + i++; + if (i > 100000) { +#if 0 + printf("forward_signal: dropped ast 0x%x\n", + checkstate_need_ast & map); +#endif + break; + } + } + if (id == (u_char) p->p_oncpu) + return; + } +} diff --git a/sys/sys/smp.h b/sys/sys/smp.h index 08fffbe3f58a..482b86015a2a 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.35 1998/02/25 03:56:15 dyson Exp $ + * $Id: smp.h,v 1.36 1998/03/03 19:44:34 tegge Exp $ * */ @@ -79,10 +79,8 @@ extern u_int ivectors[]; extern volatile u_int stopped_cpus; extern volatile u_int started_cpus; -#ifdef BETTER_CLOCK extern unsigned int checkstate_probed_cpus; extern unsigned int checkstate_need_ast; -#endif /* global data in apic_ipl.s */ extern u_int vec[]; @@ -138,6 +136,7 @@ int restart_cpus __P((u_int)); void forward_statclock __P((int pscnt)); void forward_hardclock __P((int pscnt)); #endif /* BETTER_CLOCK */ +void forward_signal __P((struct proc *)); /* global data in mpapic.c */ extern volatile lapic_t lapic; |
