Add forwarding of roundrobin to other cpus. This gives a more regular

update of cpu usage as shown by top when one process is cpu bound
(no system calls) while the system is otherwise idle (except for top).

Don't attempt to switch to the BSP in boot().  If the system was idle when
an interrupt caused a panic, this won't work.  Instead, switch to the BSP
in cpu_reset.

Remove some spurious forward_statclock/forward_hardclock warnings.
This commit is contained in:
Tor Egge 1998-05-17 22:12:14 +00:00
parent 0580d32288
commit 2f1e70693d
19 changed files with 708 additions and 103 deletions

View File

@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
* $Id: apic_vector.s,v 1.28 1998/03/05 21:45:53 tegge Exp $
* $Id: apic_vector.s,v 1.29 1998/04/22 22:49:27 tegge Exp $
*/
@ -675,7 +675,15 @@ _Xcpuast:
movl _cpuid, %eax
lock
btrl %eax, _checkstate_pending_ast
lock
btrl %eax, CNAME(resched_cpus)
jz 2f
movl $1, CNAME(want_resched)
lock
incl CNAME(want_resched_cnt)
2:
lock
incl CNAME(cpuast_cnt)
MEXITCOUNT
jmp _doreti
1:
@ -803,12 +811,27 @@ forward_irq:
SUPERALIGN_TEXT
.globl _Xcpustop
_Xcpustop:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ecx
pushl %edx
pushl %ds /* save current data segment */
pushl %es
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl $0, lapic_eoi /* End Of Interrupt to APIC */
movl _cpuid, %eax
imull $PCB_SIZE, %eax
leal CNAME(stoppcbs)(%eax), %eax
pushl %eax
call CNAME(savectx) /* Save process context */
addl $4, %esp
movl _cpuid, %eax
lock
@ -819,11 +842,26 @@ _Xcpustop:
lock
btrl %eax, _started_cpus /* started_cpus &= ~(1<<id) */
lock
btrl %eax, _stopped_cpus /* stopped_cpus &= ~(1<<id) */
movl $0, lapic_eoi /* End Of Interrupt to APIC */
test %eax, %eax
jnz 2f
movl CNAME(cpustop_restartfunc), %eax
test %eax, %eax
jz 2f
movl $0, CNAME(cpustop_restartfunc) /* One-shot */
call %eax
2:
popl %es
popl %ds /* restore previous data segment */
popl %edx
popl %ecx
popl %eax
movl %ebp, %esp
popl %ebp
iret
@ -944,12 +982,25 @@ _checkstate_pending_ast:
.globl CNAME(forward_irq_misscnt)
.globl CNAME(forward_irq_toodeepcnt)
.globl CNAME(forward_irq_hitcnt)
.globl CNAME(resched_cpus)
.globl CNAME(want_resched_cnt)
.globl CNAME(cpuast_cnt)
.globl CNAME(cpustop_restartfunc)
CNAME(forward_irq_misscnt):
.long 0
CNAME(forward_irq_hitcnt):
.long 0
CNAME(forward_irq_toodeepcnt):
.long 0
CNAME(resched_cpus):
.long 0
CNAME(want_resched_cnt):
.long 0
CNAME(cpuast_cnt):
.long 0
CNAME(cpustop_restartfunc):
.long 0
.globl _apic_pin_trigger

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $Id: genassym.c,v 1.54 1998/04/06 18:59:14 peter Exp $
* $Id: genassym.c,v 1.55 1998/05/17 18:53:11 tegge Exp $
*/
#include "opt_vm86.h"
@ -159,6 +159,9 @@ main()
printf("#define\tPCB_SAVEFPU %p\n", &pcb->pcb_savefpu);
printf("#define\tPCB_SAVEFPU_SIZE %d\n", sizeof pcb->pcb_savefpu);
printf("#define\tPCB_ONFAULT %p\n", &pcb->pcb_onfault);
#ifdef SMP
printf("#define\tPCB_SIZE %d\n", sizeof(struct pcb));
#endif
printf("#define\tTF_ES %p\n", &tf->tf_es);
printf("#define\tTF_DS %p\n", &tf->tf_ds);

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
* $Id: vm_machdep.c,v 1.105 1998/03/23 19:52:42 jlemon Exp $
* $Id: vm_machdep.c,v 1.106 1998/05/16 14:44:11 kato Exp $
*/
#include "npx.h"
@ -87,6 +87,13 @@
#include <i386/isa/isa.h>
#endif
static void cpu_reset_real __P((void));
#ifdef SMP
static void cpu_reset_proxy __P((void));
static u_int cpu_reset_proxyid;
static volatile u_int cpu_reset_proxy_active;
#endif
#ifdef BOUNCE_BUFFERS
static vm_offset_t
vm_bounce_kva __P((int size, int waitok));
@ -838,9 +845,89 @@ vunmapbuf(bp)
/*
* Force reset the processor by invalidating the entire address space!
*/
#ifdef SMP
static void
cpu_reset_proxy()
{
u_int saved_mp_lock;
cpu_reset_proxy_active = 1;
while (cpu_reset_proxy_active == 1)
; /* Wait for other cpu to disable interupts */
saved_mp_lock = mp_lock;
mp_lock = 1;
printf("cpu_reset_proxy: Grabbed mp lock for BSP\n");
cpu_reset_proxy_active = 3;
while (cpu_reset_proxy_active == 3)
; /* Wait for other cpu to enable interrupts */
stop_cpus((1<<cpu_reset_proxyid));
printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid);
DELAY(1000000);
cpu_reset_real();
}
#endif
void
cpu_reset()
{
#ifdef SMP
if (smp_active == 0) {
cpu_reset_real();
/* NOTREACHED */
} else {
u_int map;
int cnt;
printf("cpu_reset called on cpu#%d\n",cpuid);
map = other_cpus & ~ stopped_cpus;
if (map != 0) {
printf("cpu_reset: Stopping other CPUs\n");
stop_cpus(map); /* Stop all other CPUs */
}
if (cpuid == 0) {
DELAY(1000000);
cpu_reset_real();
/* NOTREACHED */
} else {
/* We are not BSP (CPU #0) */
cpu_reset_proxyid = cpuid;
cpustop_restartfunc = cpu_reset_proxy;
printf("cpu_reset: Restarting BSP\n");
started_cpus = (1<<0); /* Restart CPU #0 */
cnt = 0;
while (cpu_reset_proxy_active == 0 && cnt < 10000000)
cnt++; /* Wait for BSP to announce restart */
if (cpu_reset_proxy_active == 0)
printf("cpu_reset: Failed to restart BSP\n");
__asm __volatile("cli" : : : "memory");
cpu_reset_proxy_active = 2;
cnt = 0;
while (cpu_reset_proxy_active == 2 && cnt < 10000000)
cnt++; /* Do nothing */
if (cpu_reset_proxy_active == 2) {
printf("cpu_reset: BSP did not grab mp lock\n");
cpu_reset_real(); /* XXX: Bogus ? */
}
cpu_reset_proxy_active = 4;
__asm __volatile("sti" : : : "memory");
while (1);
/* NOTREACHED */
}
}
#else
cpu_reset_real();
#endif
}
static void
cpu_reset_real()
{
#ifdef PC98
/*

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -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.41 1998/04/01 20:38:28 tegge Exp $
* $Id: smp.h,v 1.42 1998/04/01 21:07:36 tegge Exp $
*
*/
@ -80,6 +80,8 @@ extern volatile u_int started_cpus;
extern volatile u_int checkstate_probed_cpus;
extern volatile u_int checkstate_need_ast;
extern volatile u_int resched_cpus;
extern void (*cpustop_restartfunc) __P((void));
/* functions in apic_ipl.s */
void apic_eoi __P((void));
@ -103,6 +105,7 @@ extern int io_num_to_apic_id[];
extern int apic_id_to_logical[];
extern u_int all_cpus;
extern u_char SMP_ioapic[];
extern struct pcb stoppcbs[];
/* functions in mp_machdep.c */
u_int mp_bootaddress __P((u_int));
@ -131,6 +134,7 @@ void forward_statclock __P((int pscnt));
void forward_hardclock __P((int pscnt));
#endif /* BETTER_CLOCK */
void forward_signal __P((struct proc *));
void forward_roundrobin __P((void));
#ifdef APIC_INTR_REORDER
void set_lapic_isrloc __P((int, int));
#endif /* APIC_INTR_REORDER */

View File

@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
* $Id: apic_vector.s,v 1.28 1998/03/05 21:45:53 tegge Exp $
* $Id: apic_vector.s,v 1.29 1998/04/22 22:49:27 tegge Exp $
*/
@ -675,7 +675,15 @@ _Xcpuast:
movl _cpuid, %eax
lock
btrl %eax, _checkstate_pending_ast
lock
btrl %eax, CNAME(resched_cpus)
jz 2f
movl $1, CNAME(want_resched)
lock
incl CNAME(want_resched_cnt)
2:
lock
incl CNAME(cpuast_cnt)
MEXITCOUNT
jmp _doreti
1:
@ -803,12 +811,27 @@ forward_irq:
SUPERALIGN_TEXT
.globl _Xcpustop
_Xcpustop:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ecx
pushl %edx
pushl %ds /* save current data segment */
pushl %es
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl $0, lapic_eoi /* End Of Interrupt to APIC */
movl _cpuid, %eax
imull $PCB_SIZE, %eax
leal CNAME(stoppcbs)(%eax), %eax
pushl %eax
call CNAME(savectx) /* Save process context */
addl $4, %esp
movl _cpuid, %eax
lock
@ -819,11 +842,26 @@ _Xcpustop:
lock
btrl %eax, _started_cpus /* started_cpus &= ~(1<<id) */
lock
btrl %eax, _stopped_cpus /* stopped_cpus &= ~(1<<id) */
movl $0, lapic_eoi /* End Of Interrupt to APIC */
test %eax, %eax
jnz 2f
movl CNAME(cpustop_restartfunc), %eax
test %eax, %eax
jz 2f
movl $0, CNAME(cpustop_restartfunc) /* One-shot */
call %eax
2:
popl %es
popl %ds /* restore previous data segment */
popl %edx
popl %ecx
popl %eax
movl %ebp, %esp
popl %ebp
iret
@ -944,12 +982,25 @@ _checkstate_pending_ast:
.globl CNAME(forward_irq_misscnt)
.globl CNAME(forward_irq_toodeepcnt)
.globl CNAME(forward_irq_hitcnt)
.globl CNAME(resched_cpus)
.globl CNAME(want_resched_cnt)
.globl CNAME(cpuast_cnt)
.globl CNAME(cpustop_restartfunc)
CNAME(forward_irq_misscnt):
.long 0
CNAME(forward_irq_hitcnt):
.long 0
CNAME(forward_irq_toodeepcnt):
.long 0
CNAME(resched_cpus):
.long 0
CNAME(want_resched_cnt):
.long 0
CNAME(cpuast_cnt):
.long 0
CNAME(cpustop_restartfunc):
.long 0
.globl _apic_pin_trigger

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $Id: genassym.c,v 1.54 1998/04/06 18:59:14 peter Exp $
* $Id: genassym.c,v 1.55 1998/05/17 18:53:11 tegge Exp $
*/
#include "opt_vm86.h"
@ -159,6 +159,9 @@ main()
printf("#define\tPCB_SAVEFPU %p\n", &pcb->pcb_savefpu);
printf("#define\tPCB_SAVEFPU_SIZE %d\n", sizeof pcb->pcb_savefpu);
printf("#define\tPCB_ONFAULT %p\n", &pcb->pcb_onfault);
#ifdef SMP
printf("#define\tPCB_SIZE %d\n", sizeof(struct pcb));
#endif
printf("#define\tTF_ES %p\n", &tf->tf_es);
printf("#define\tTF_DS %p\n", &tf->tf_ds);

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
* $Id: vm_machdep.c,v 1.105 1998/03/23 19:52:42 jlemon Exp $
* $Id: vm_machdep.c,v 1.106 1998/05/16 14:44:11 kato Exp $
*/
#include "npx.h"
@ -87,6 +87,13 @@
#include <i386/isa/isa.h>
#endif
static void cpu_reset_real __P((void));
#ifdef SMP
static void cpu_reset_proxy __P((void));
static u_int cpu_reset_proxyid;
static volatile u_int cpu_reset_proxy_active;
#endif
#ifdef BOUNCE_BUFFERS
static vm_offset_t
vm_bounce_kva __P((int size, int waitok));
@ -838,9 +845,89 @@ vunmapbuf(bp)
/*
* Force reset the processor by invalidating the entire address space!
*/
#ifdef SMP
static void
cpu_reset_proxy()
{
u_int saved_mp_lock;
cpu_reset_proxy_active = 1;
while (cpu_reset_proxy_active == 1)
; /* Wait for other cpu to disable interupts */
saved_mp_lock = mp_lock;
mp_lock = 1;
printf("cpu_reset_proxy: Grabbed mp lock for BSP\n");
cpu_reset_proxy_active = 3;
while (cpu_reset_proxy_active == 3)
; /* Wait for other cpu to enable interrupts */
stop_cpus((1<<cpu_reset_proxyid));
printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid);
DELAY(1000000);
cpu_reset_real();
}
#endif
void
cpu_reset()
{
#ifdef SMP
if (smp_active == 0) {
cpu_reset_real();
/* NOTREACHED */
} else {
u_int map;
int cnt;
printf("cpu_reset called on cpu#%d\n",cpuid);
map = other_cpus & ~ stopped_cpus;
if (map != 0) {
printf("cpu_reset: Stopping other CPUs\n");
stop_cpus(map); /* Stop all other CPUs */
}
if (cpuid == 0) {
DELAY(1000000);
cpu_reset_real();
/* NOTREACHED */
} else {
/* We are not BSP (CPU #0) */
cpu_reset_proxyid = cpuid;
cpustop_restartfunc = cpu_reset_proxy;
printf("cpu_reset: Restarting BSP\n");
started_cpus = (1<<0); /* Restart CPU #0 */
cnt = 0;
while (cpu_reset_proxy_active == 0 && cnt < 10000000)
cnt++; /* Wait for BSP to announce restart */
if (cpu_reset_proxy_active == 0)
printf("cpu_reset: Failed to restart BSP\n");
__asm __volatile("cli" : : : "memory");
cpu_reset_proxy_active = 2;
cnt = 0;
while (cpu_reset_proxy_active == 2 && cnt < 10000000)
cnt++; /* Do nothing */
if (cpu_reset_proxy_active == 2) {
printf("cpu_reset: BSP did not grab mp lock\n");
cpu_reset_real(); /* XXX: Bogus ? */
}
cpu_reset_proxy_active = 4;
__asm __volatile("sti" : : : "memory");
while (1);
/* NOTREACHED */
}
}
#else
cpu_reset_real();
#endif
}
static void
cpu_reset_real()
{
#ifdef PC98
/*

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -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.41 1998/04/01 20:38:28 tegge Exp $
* $Id: smp.h,v 1.42 1998/04/01 21:07:36 tegge Exp $
*
*/
@ -80,6 +80,8 @@ extern volatile u_int started_cpus;
extern volatile u_int checkstate_probed_cpus;
extern volatile u_int checkstate_need_ast;
extern volatile u_int resched_cpus;
extern void (*cpustop_restartfunc) __P((void));
/* functions in apic_ipl.s */
void apic_eoi __P((void));
@ -103,6 +105,7 @@ extern int io_num_to_apic_id[];
extern int apic_id_to_logical[];
extern u_int all_cpus;
extern u_char SMP_ioapic[];
extern struct pcb stoppcbs[];
/* functions in mp_machdep.c */
u_int mp_bootaddress __P((u_int));
@ -131,6 +134,7 @@ void forward_statclock __P((int pscnt));
void forward_hardclock __P((int pscnt));
#endif /* BETTER_CLOCK */
void forward_signal __P((struct proc *));
void forward_roundrobin __P((void));
#ifdef APIC_INTR_REORDER
void set_lapic_isrloc __P((int, int));
#endif /* APIC_INTR_REORDER */

View File

@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
* $Id: apic_vector.s,v 1.28 1998/03/05 21:45:53 tegge Exp $
* $Id: apic_vector.s,v 1.29 1998/04/22 22:49:27 tegge Exp $
*/
@ -675,7 +675,15 @@ _Xcpuast:
movl _cpuid, %eax
lock
btrl %eax, _checkstate_pending_ast
lock
btrl %eax, CNAME(resched_cpus)
jz 2f
movl $1, CNAME(want_resched)
lock
incl CNAME(want_resched_cnt)
2:
lock
incl CNAME(cpuast_cnt)
MEXITCOUNT
jmp _doreti
1:
@ -803,12 +811,27 @@ forward_irq:
SUPERALIGN_TEXT
.globl _Xcpustop
_Xcpustop:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ecx
pushl %edx
pushl %ds /* save current data segment */
pushl %es
movl $KDSEL, %eax
movl %ax, %ds /* use KERNEL data segment */
movl $0, lapic_eoi /* End Of Interrupt to APIC */
movl _cpuid, %eax
imull $PCB_SIZE, %eax
leal CNAME(stoppcbs)(%eax), %eax
pushl %eax
call CNAME(savectx) /* Save process context */
addl $4, %esp
movl _cpuid, %eax
lock
@ -819,11 +842,26 @@ _Xcpustop:
lock
btrl %eax, _started_cpus /* started_cpus &= ~(1<<id) */
lock
btrl %eax, _stopped_cpus /* stopped_cpus &= ~(1<<id) */
movl $0, lapic_eoi /* End Of Interrupt to APIC */
test %eax, %eax
jnz 2f
movl CNAME(cpustop_restartfunc), %eax
test %eax, %eax
jz 2f
movl $0, CNAME(cpustop_restartfunc) /* One-shot */
call %eax
2:
popl %es
popl %ds /* restore previous data segment */
popl %edx
popl %ecx
popl %eax
movl %ebp, %esp
popl %ebp
iret
@ -944,12 +982,25 @@ _checkstate_pending_ast:
.globl CNAME(forward_irq_misscnt)
.globl CNAME(forward_irq_toodeepcnt)
.globl CNAME(forward_irq_hitcnt)
.globl CNAME(resched_cpus)
.globl CNAME(want_resched_cnt)
.globl CNAME(cpuast_cnt)
.globl CNAME(cpustop_restartfunc)
CNAME(forward_irq_misscnt):
.long 0
CNAME(forward_irq_hitcnt):
.long 0
CNAME(forward_irq_toodeepcnt):
.long 0
CNAME(resched_cpus):
.long 0
CNAME(want_resched_cnt):
.long 0
CNAME(cpuast_cnt):
.long 0
CNAME(cpustop_restartfunc):
.long 0
.globl _apic_pin_trigger

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94
* $Id: kern_shutdown.c,v 1.30 1998/05/06 22:14:48 julian Exp $
* $Id: kern_shutdown.c,v 1.31 1998/05/12 17:34:02 bde Exp $
*/
#include "opt_ddb.h"
@ -176,23 +176,8 @@ boot(howto)
sle_p ep;
#ifdef SMP
int c, spins;
/* The MPSPEC says that the BSP must do the shutdown */
if (smp_active) {
smp_active = 0;
spins = 100;
printf("boot() called on cpu#%d\n", cpuid);
while ((c = cpuid) != 0) {
if (spins-- < 1) {
printf("timeout waiting for cpu #0!\n");
break;
}
printf("I'm on cpu#%d, I need to be on cpu#0, sleeping..\n", c);
tsleep((caddr_t)&smp_active, PZERO, "cpu0wt", 10);
}
}
#endif
/*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
* $Id: kern_synch.c,v 1.54 1998/04/04 13:25:20 phk Exp $
* $Id: kern_synch.c,v 1.55 1998/05/17 11:52:45 phk Exp $
*/
#include "opt_ktrace.h"
@ -57,6 +57,10 @@
#endif
#include <machine/cpu.h>
#ifdef SMP
#include <machine/smp.h>
#endif
#include <machine/ipl.h>
#include <machine/limits.h> /* for UCHAR_MAX = typeof(p_priority)_MAX */
static void rqinit __P((void *));
@ -130,8 +134,13 @@ roundrobin(arg)
{
struct proc *p = curproc; /* XXX */
#ifdef SMP
need_resched();
forward_roundrobin();
#else
if (p == 0 || RTP_PRIO_NEED_RR(p->p_rtprio.type))
need_resched();
#endif
timeout(roundrobin, NULL, ROUNDROBIN_INTERVAL);
}

View File

@ -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.74 1998/05/11 01:06:06 dyson Exp $
* $Id: mp_machdep.c,v 1.75 1998/05/17 18:53:17 tegge Exp $
*/
#include "opt_smp.h"
@ -312,6 +312,8 @@ extern pt_entry_t SMP_prvpt[];
/* Private page pointer to curcpu's PTD, used during BSP init */
extern pd_entry_t *my_idlePTD;
struct pcb stoppcbs[NCPU];
static int smp_started; /* has the system started? */
/*
@ -2009,13 +2011,10 @@ stop_cpus(u_int map)
if (!smp_started)
return 0;
/* send IPI to all CPUs in map */
stopped_cpus = 0;
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
while (stopped_cpus != map)
while ((stopped_cpus & map) != map)
/* spin */ ;
return 1;
@ -2043,9 +2042,8 @@ restart_cpus(u_int map)
started_cpus = map; /* signal other cpus to restart */
while (started_cpus) /* wait for each to clear its bit */
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
/* spin */ ;
stopped_cpus = 0;
return 1;
}
@ -2075,6 +2073,11 @@ int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0, "");
/* Enable forwarding of roundrobin to all other cpus */
int forward_roundrobin_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
&forward_roundrobin_enabled, 0, "");
/*
* This is called once the rest of the system is up and running and we're
* ready to let the AP's out of the pen.
@ -2296,9 +2299,11 @@ forward_statclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_statclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2369,9 +2374,11 @@ forward_hardclock(int pscnt)
while (checkstate_probed_cpus != map) {
/* spin */
i++;
if (i == 1000000) {
if (i == 100000) {
#ifdef BETTER_CLOCK_DIAGNOSTIC
printf("forward_hardclock: checkstate %x\n",
checkstate_probed_cpus);
#endif
break;
}
}
@ -2475,6 +2482,37 @@ forward_signal(struct proc *p)
}
}
void
forward_roundrobin(void)
{
u_int map;
int i;
if (!smp_started || !invltlb_ok || cold || panicstr)
return;
if (!forward_roundrobin_enabled)
return;
resched_cpus |= other_cpus;
map = other_cpus & ~stopped_cpus ;
#if 1
selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED);
#else
(void) all_but_self_ipi(XCPUAST_OFFSET);
#endif
i = 0;
while ((checkstate_need_ast & map) != 0) {
/* spin */
i++;
if (i > 100000) {
#if 0
printf("forward_roundrobin: dropped ast 0x%x\n",
checkstate_need_ast & map);
#endif
break;
}
}
}
#ifdef APIC_INTR_REORDER
/*

View File

@ -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.41 1998/04/01 20:38:28 tegge Exp $
* $Id: smp.h,v 1.42 1998/04/01 21:07:36 tegge Exp $
*
*/
@ -80,6 +80,8 @@ extern volatile u_int started_cpus;
extern volatile u_int checkstate_probed_cpus;
extern volatile u_int checkstate_need_ast;
extern volatile u_int resched_cpus;
extern void (*cpustop_restartfunc) __P((void));
/* functions in apic_ipl.s */
void apic_eoi __P((void));
@ -103,6 +105,7 @@ extern int io_num_to_apic_id[];
extern int apic_id_to_logical[];
extern u_int all_cpus;
extern u_char SMP_ioapic[];
extern struct pcb stoppcbs[];
/* functions in mp_machdep.c */
u_int mp_bootaddress __P((u_int));
@ -131,6 +134,7 @@ void forward_statclock __P((int pscnt));
void forward_hardclock __P((int pscnt));
#endif /* BETTER_CLOCK */
void forward_signal __P((struct proc *));
void forward_roundrobin __P((void));
#ifdef APIC_INTR_REORDER
void set_lapic_isrloc __P((int, int));
#endif /* APIC_INTR_REORDER */