The promised "better fix" for "Trap 9 When Boot SMP" problem.

We now tsleep() in kthread_init() between start_init()
and prepare_usermode() while waiting for ALL the idle_loop()
processes to come online.

Debugged & tested by:	"Thomas D. Dean" <tomdean@ix.netcom.com>

Reviewed by:	David Greenman <dg@root.com>
This commit is contained in:
fsmp 1997-08-15 02:33:30 +00:00
parent b458c644f8
commit 36308aa291
2 changed files with 18 additions and 29 deletions

View File

@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
* $Id: init_main.c,v 1.67 1997/08/05 00:01:21 dyson Exp $
* $Id: init_main.c,v 1.5 1997/08/15 02:13:31 smp Exp smp $
*/
#include "opt_rlimit.h"
@ -62,6 +62,9 @@
#include <sys/vmmeter.h>
#include <machine/cpu.h>
#ifdef SMP
#include <machine/smp.h>
#endif /* SMP */
#include <vm/vm.h>
#include <vm/vm_param.h>
@ -535,10 +538,15 @@ static void
kthread_init(dummy)
void *dummy;
{
/* Create process 1 (init(8)). */
start_init(curproc);
#ifdef SMP
/* wait for the SMP idle loops to come online */
while (smp_idle_loops < mp_ncpus)
tsleep((caddr_t *)&smp_idle_loops, PWAIT, "smpilw", 0);
#endif /* SMP */
prepare_usermode();
/*

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: init_smp.c,v 1.13 1997/07/22 16:49:54 fsmp Exp $
* $Id: init_smp.c,v 1.10 1997/08/15 02:13:31 smp Exp smp $
*/
#include "opt_smp.h"
@ -44,7 +44,7 @@
#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/smptests.h> /** IGNORE_IDLEPROCS, TEST_TEST1 */
#include <machine/smptests.h> /** IGNORE_IDLEPROCS */
#include <machine/specialreg.h>
#include <vm/vm.h>
@ -54,10 +54,6 @@
#include <vm/vm_map.h>
#include <sys/user.h>
#if defined(TEST_TEST1)
void ipi_test1(void);
#endif /** TEST_TEST1 */
int smp_active = 0; /* are the APs allowed to run? */
static int
@ -108,7 +104,7 @@ static void smp_idleloop __P((void *));
void secondary_main __P((void));
static int idle_loops = 0;
volatile int smp_idle_loops = 0;
void boot_unlock __P((void));
struct proc *SMPidleproc[NCPU];
@ -134,7 +130,6 @@ smp_kickoff(dummy)
SMPidleproc[i] = p;
p->p_flag |= P_INMEM | P_SYSTEM | P_IDLEPROC;
sprintf(p->p_comm, "cpuidle%d", i);
/*
* PRIO_IDLE is the last scheduled of the three
* classes and we choose the lowest priority possible
@ -186,15 +181,7 @@ secondary_main()
printf("SMP: AP CPU #%d LAUNCHED!! Starting Scheduling...\n",
cpuid);
#if defined(TEST_TEST1)
/* XXX this would be dangerous for > 2 CPUs! */
if (cpuid == IPI_TARGET_TEST1) {
lapic.tpr = 0xff;
ipi_test1();
}
#endif /** TEST_TEST1 */
/* Setup the FPU. */
/* XXX FIXME: i386 specific, and redundant: Setup the FPU. */
load_cr0((rcr0() & ~CR0_EM) | CR0_MP | CR0_NE | CR0_TS);
curproc = NULL; /* ensure no context to save */
@ -215,24 +202,18 @@ void *dummy;
int dcnt = 0;
int apic_id;
#if 1
/*
* XXX FIXME: cheap fix for "trap 9 on boot" problem.
* this is temporary, but seems to be the most benign of our choices.
* expected to be fixed properly "real soon now".
*/
asm("pushl %ds; popl %es");
#endif
/*
* This code is executed only on startup of the idleprocs
* The fact that this is executed is an indication that the
* idle procs are online and it's safe to kick off the first
* AP cpu.
*/
if ( ++idle_loops == mp_ncpus ) {
if ( ++smp_idle_loops == mp_ncpus ) {
printf("SMP: All idle procs online.\n");
/* let the init process finish */
wakeup((caddr_t *)&smp_idle_loops);
#ifndef NO_AUTOSTART
printf("SMP: *** AUTO *** starting 1st AP!\n");
smp_cpus = 1;