aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTor Egge <tegge@FreeBSD.org>1998-03-03 20:55:26 +0000
committerTor Egge <tegge@FreeBSD.org>1998-03-03 20:55:26 +0000
commit3163861c7bb17056051e94ed6a8e34108a4d7ce0 (patch)
treed39f111e4c67aa276feecb7cb8b2ff7a7c676367 /sys
parentfe9cd27373ba2d41a792f8857ed4dd9205a29f88 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/apic_vector.S10
-rw-r--r--sys/amd64/amd64/mp_machdep.c56
-rw-r--r--sys/amd64/amd64/mptable.c56
-rw-r--r--sys/amd64/include/mptable.h56
-rw-r--r--sys/amd64/include/smp.h5
-rw-r--r--sys/amd64/isa/intr_machdep.h8
-rw-r--r--sys/i386/i386/apic_vector.s10
-rw-r--r--sys/i386/i386/mp_machdep.c56
-rw-r--r--sys/i386/i386/mptable.c56
-rw-r--r--sys/i386/include/mptable.h56
-rw-r--r--sys/i386/include/smp.h5
-rw-r--r--sys/i386/isa/apic_vector.s10
-rw-r--r--sys/i386/isa/intr_machdep.h8
-rw-r--r--sys/kern/kern_sig.c9
-rw-r--r--sys/kern/subr_smp.c56
-rw-r--r--sys/sys/smp.h5
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;