changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: kernel: cleanup exit()/shutdown()/reboot() code

changeset 4993: 7e93ea0d48d1
parent 4989: 64b30578e9f9
child 4994: fd2679f55a3d
author: cinap_lenrek@felloff.net
date: Mon, 30 Nov 2015 14:56:00 +0100
files: sys/src/9/alphapc/dat.h sys/src/9/alphapc/main.c sys/src/9/bcm/dat.h sys/src/9/bcm/main.c sys/src/9/bitsy/dat.h sys/src/9/bitsy/main.c sys/src/9/kw/dat.h sys/src/9/kw/main.c sys/src/9/mtx/dat.h sys/src/9/mtx/main.c sys/src/9/omap/dat.h sys/src/9/omap/main.c sys/src/9/omap4/dat.h sys/src/9/pc/dat.h sys/src/9/pc/main.c sys/src/9/pc/screen.c sys/src/9/pc64/dat.h sys/src/9/pc64/main.c sys/src/9/port/allocb.c sys/src/9/port/devcons.c sys/src/9/port/portfns.h sys/src/9/port/rebootcmd.c sys/src/9/port/ucallocb.c sys/src/9/ppc/dat.h sys/src/9/ppc/main.c sys/src/9/sgi/dat.h sys/src/9/sgi/main.c sys/src/9/teg2/dat.h sys/src/9/teg2/main.c sys/src/9/xen/main.c sys/src/9/zynq/dat.h sys/src/9/zynq/main.c
description: kernel: cleanup exit()/shutdown()/reboot() code

introduce cpushutdown() function that does the common
operation of initiating shutdown, returning once all
cpu's got the message and are about to shutdown. this
avoids duplicated code which isnt really machine specific.

automatic reboot on panic only when *debug= is not set
and the machine is a cpu server or has no display,
otherwise just hang.
     1.1--- a/sys/src/9/alphapc/dat.h
     1.2+++ b/sys/src/9/alphapc/dat.h
     1.3@@ -186,7 +186,6 @@ struct
     1.4 	Lock;
     1.5 	short	machs;
     1.6 	short	exiting;
     1.7-	short	ispanic;
     1.8 }active;
     1.9 
    1.10 /*
     2.1--- a/sys/src/9/alphapc/main.c
     2.2+++ b/sys/src/9/alphapc/main.c
     2.3@@ -308,123 +308,21 @@ setupboot(int halt)
     2.4 	cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot);
     2.5 }
     2.6 
     2.7-/* from ../pc */
     2.8-static void
     2.9-shutdown(int ispanic)
    2.10-{
    2.11-	int ms, once;
    2.12-
    2.13-	lock(&active);
    2.14-	if(ispanic)
    2.15-		active.ispanic = ispanic;
    2.16-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
    2.17-		active.ispanic = 0;
    2.18-	once = active.machs & (1<<m->machno);
    2.19-	active.machs &= ~(1<<m->machno);
    2.20-	active.exiting = 1;
    2.21-	unlock(&active);
    2.22-
    2.23-	if(once)
    2.24-		print("cpu%d: exiting\n", m->machno);
    2.25-	spllo();
    2.26-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
    2.27-		delay(TK2MS(2));
    2.28-		if(active.machs == 0 && consactive() == 0)
    2.29-			break;
    2.30-	}
    2.31-
    2.32-	if(active.ispanic && m->machno == 0) {
    2.33-		if(cpuserver)
    2.34-			delay(10000);
    2.35-		else
    2.36-			for (;;)
    2.37-				continue;
    2.38-	} else
    2.39-		delay(1000);
    2.40-}
    2.41-
    2.42-/* from ../pc: */
    2.43 void
    2.44-reboot(void *entry, void *code, ulong size)
    2.45+reboot(void *, void *, ulong)
    2.46 {
    2.47-	// writeconf();		// pass kernel environment to next kernel
    2.48-	shutdown(0);
    2.49-
    2.50-	/*
    2.51-	 * should be the only processor running now
    2.52-	 */
    2.53-	print("shutting down...\n");
    2.54-	delay(200);
    2.55-
    2.56-	splhi();
    2.57-
    2.58-	/* turn off buffered serial console */
    2.59-	serialoq = nil;
    2.60-
    2.61-	/* shutdown devices */
    2.62-	chandevshutdown();
    2.63-
    2.64-#ifdef FUTURE
    2.65-{
    2.66-	ulong *pdb;
    2.67-	/*
    2.68-	 * Modify the machine page table to directly map the low 4MB of memory
    2.69-	 * This allows the reboot code to turn off the page mapping
    2.70-	 */
    2.71-	pdb = m->pdb;
    2.72-	pdb[PDX(0)] = pdb[PDX(KZERO)];
    2.73-	mmuflushtlb(PADDR(pdb));
    2.74-}
    2.75-	/* setup reboot trampoline function */
    2.76-{
    2.77-	void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
    2.78-
    2.79-	memmove(f, rebootcode, sizeof(rebootcode));
    2.80-#else
    2.81-	USED(entry, code, size);
    2.82-#endif
    2.83-
    2.84-	print("rebooting...\n");
    2.85-#ifdef FUTURE
    2.86-	/* off we go - never to return */
    2.87-	(*f)(PADDR(entry), PADDR(code), size);
    2.88-}
    2.89-#endif
    2.90-	setupboot(0);		// reboot, don't halt
    2.91-	exit(0);
    2.92 }
    2.93 
    2.94 void
    2.95-exit(int ispanic)
    2.96+exit(int)
    2.97 {
    2.98-	canlock(&active);
    2.99-	active.machs &= ~(1<<m->machno);
   2.100-	active.exiting = 1;
   2.101-	unlock(&active);
   2.102-
   2.103-	spllo();
   2.104-	print("cpu %d exiting\n", m->machno);
   2.105-	do
   2.106-		delay(100);
   2.107-	while(consactive());
   2.108-
   2.109+	cpushutdown();
   2.110 	splhi();
   2.111-	delay(1000);	/* give serial fifo time to finish flushing */
   2.112-	if (getconf("*debug") != nil) {
   2.113-		USED(ispanic);
   2.114-		delay(60*1000);		/* give us time to read the screen */
   2.115-	}
   2.116 	if(arch->coredetach)
   2.117 		arch->coredetach();
   2.118 	setupboot(1);			// set up to halt
   2.119-	for (; ; )
   2.120+	for (;;)
   2.121 		firmware();
   2.122-
   2.123-	// on PC is just:
   2.124-	//if (0) {
   2.125-	//	shutdown(ispanic);
   2.126-	//	arch->reset();
   2.127-	//}
   2.128 }
   2.129 
   2.130 void
     3.1--- a/sys/src/9/bcm/dat.h
     3.2+++ b/sys/src/9/bcm/dat.h
     3.3@@ -225,7 +225,6 @@ struct
     3.4 	Lock;
     3.5 	int	machs;			/* bitmap of active CPUs */
     3.6 	int	exiting;		/* shutdown */
     3.7-	int	ispanic;		/* shutdown in response to a panic */
     3.8 }active;
     3.9 
    3.10 extern register Mach* m;			/* R10 */
     4.1--- a/sys/src/9/bcm/main.c
     4.2+++ b/sys/src/9/bcm/main.c
     4.3@@ -522,39 +522,13 @@ confinit(void)
     4.4 
     4.5 }
     4.6 
     4.7-static void
     4.8-shutdown(int ispanic)
     4.9-{
    4.10-	int ms, once;
    4.11-
    4.12-	lock(&active);
    4.13-	if(ispanic)
    4.14-		active.ispanic = ispanic;
    4.15-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
    4.16-		active.ispanic = 0;
    4.17-	once = active.machs & (1<<m->machno);
    4.18-	active.machs &= ~(1<<m->machno);
    4.19-	active.exiting = 1;
    4.20-	unlock(&active);
    4.21-
    4.22-	if(once)
    4.23-		iprint("cpu%d: exiting\n", m->machno);
    4.24-	spllo();
    4.25-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
    4.26-		delay(TK2MS(2));
    4.27-		if(active.machs == 0 && consactive() == 0)
    4.28-			break;
    4.29-	}
    4.30-	delay(1000);
    4.31-}
    4.32-
    4.33 /*
    4.34  *  exit kernel either on a panic or user request
    4.35  */
    4.36 void
    4.37-exit(int code)
    4.38+exit(int)
    4.39 {
    4.40-	shutdown(code);
    4.41+	cpushutdown();
    4.42 	splfhi();
    4.43 	archreboot();
    4.44 }
    4.45@@ -579,17 +553,8 @@ reboot(void *entry, void *code, ulong si
    4.46 {
    4.47 	void (*f)(ulong, ulong, ulong);
    4.48 
    4.49-	print("starting reboot...");
    4.50 	writeconf();
    4.51-	shutdown(0);
    4.52-
    4.53-	/*
    4.54-	 * should be the only processor running now
    4.55-	 */
    4.56-
    4.57-	print("reboot entry %#lux code %#lux size %ld\n",
    4.58-		PADDR(entry), PADDR(code), size);
    4.59-	delay(100);
    4.60+	cpushutdown();
    4.61 
    4.62 	/* turn off buffered serial console */
    4.63 	serialoq = nil;
    4.64@@ -612,10 +577,6 @@ reboot(void *entry, void *code, ulong si
    4.65 
    4.66 	/* off we go - never to return */
    4.67 	(*f)(PADDR(entry), PADDR(code), size);
    4.68-
    4.69-	iprint("loaded kernel returned!\n");
    4.70-	delay(1000);
    4.71-	archreboot();
    4.72 }
    4.73 
    4.74 int
     5.1--- a/sys/src/9/bitsy/dat.h
     5.2+++ b/sys/src/9/bitsy/dat.h
     5.3@@ -180,7 +180,6 @@ struct
     5.4 	Lock;
     5.5 	int	machs;			/* bitmap of active CPUs */
     5.6 	int	exiting;		/* shutdown */
     5.7-	int	ispanic;		/* shutdown in response to a panic */
     5.8 }active;
     5.9 
    5.10 #define	MACHP(n)	((Mach *)(MACHADDR+(n)*BY2PG))
     6.1--- a/sys/src/9/bitsy/main.c
     6.2+++ b/sys/src/9/bitsy/main.c
     6.3@@ -56,7 +56,6 @@ main(void)
     6.4 void
     6.5 reboot(void*, void*, ulong)
     6.6 {
     6.7-	exit(0);
     6.8 }
     6.9 
    6.10 
    6.11@@ -64,13 +63,12 @@ reboot(void*, void*, ulong)
    6.12  *  exit kernel either on a panic or user request
    6.13  */
    6.14 void
    6.15-exit(int ispanic)
    6.16+exit(int)
    6.17 {
    6.18 	void (*f)(void);
    6.19 
    6.20-	USED(ispanic);
    6.21-	delay(1000);
    6.22-
    6.23+	cpushutdown();
    6.24+	splhi();
    6.25 	iprint("it's a wonderful day to die\n");
    6.26 	cacheflush();
    6.27 	mmuinvalidate();
     7.1--- a/sys/src/9/kw/dat.h
     7.2+++ b/sys/src/9/kw/dat.h
     7.3@@ -196,7 +196,6 @@ struct
     7.4 	Lock;
     7.5 	int	machs;			/* bitmap of active CPUs */
     7.6 	int	exiting;		/* shutdown */
     7.7-	int	ispanic;		/* shutdown in response to a panic */
     7.8 }active;
     7.9 
    7.10 enum {
     8.1--- a/sys/src/9/kw/main.c
     8.2+++ b/sys/src/9/kw/main.c
     8.3@@ -355,39 +355,13 @@ machinit(void)
     8.4 	up = nil;
     8.5 }
     8.6 
     8.7-static void
     8.8-shutdown(int ispanic)
     8.9-{
    8.10-	int ms, once;
    8.11-
    8.12-	lock(&active);
    8.13-	if(ispanic)
    8.14-		active.ispanic = ispanic;
    8.15-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
    8.16-		active.ispanic = 0;
    8.17-	once = active.machs & (1<<m->machno);
    8.18-	active.machs &= ~(1<<m->machno);
    8.19-	active.exiting = 1;
    8.20-	unlock(&active);
    8.21-
    8.22-	if(once)
    8.23-		iprint("cpu%d: exiting\n", m->machno);
    8.24-	spllo();
    8.25-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
    8.26-		delay(TK2MS(2));
    8.27-		if(active.machs == 0 && consactive() == 0)
    8.28-			break;
    8.29-	}
    8.30-	delay(1000);
    8.31-}
    8.32-
    8.33 /*
    8.34  *  exit kernel either on a panic or user request
    8.35  */
    8.36 void
    8.37-exit(int code)
    8.38+exit(int)
    8.39 {
    8.40-	shutdown(code);
    8.41+	cpushutdown();
    8.42 	splhi();
    8.43 	archreboot();
    8.44 }
    8.45@@ -401,17 +375,8 @@ reboot(void *entry, void *code, ulong si
    8.46 {
    8.47 	void (*f)(ulong, ulong, ulong);
    8.48 
    8.49-	iprint("starting reboot...");
    8.50 	writeconf();
    8.51-	
    8.52-	shutdown(0);
    8.53-
    8.54-	/*
    8.55-	 * should be the only processor running now
    8.56-	 */
    8.57-
    8.58-	print("shutting down...\n");
    8.59-	delay(200);
    8.60+	cpushutdown();
    8.61 
    8.62 	/* turn off buffered serial console */
    8.63 	serialoq = nil;
    8.64@@ -430,19 +395,10 @@ reboot(void *entry, void *code, ulong si
    8.65 	cacheuwbinv();
    8.66 	l2cacheuwb();
    8.67 
    8.68-	print("rebooting...");
    8.69-	iprint("entry %#lux code %#lux size %ld\n",
    8.70-		PADDR(entry), PADDR(code), size);
    8.71-	delay(100);		/* wait for uart to quiesce */
    8.72-
    8.73 	/* off we go - never to return */
    8.74 	cacheuwbinv();
    8.75 	l2cacheuwb();
    8.76 	(*f)(PADDR(entry), PADDR(code), size);
    8.77-
    8.78-	iprint("loaded kernel returned!\n");
    8.79-	delay(1000);
    8.80-	archreboot();
    8.81 }
    8.82 
    8.83 /*
     9.1--- a/sys/src/9/mtx/dat.h
     9.2+++ b/sys/src/9/mtx/dat.h
     9.3@@ -183,7 +183,6 @@ struct
     9.4 	Lock;
     9.5 	short	machs;
     9.6 	short	exiting;
     9.7-	short	ispanic;
     9.8 }active;
     9.9 
    9.10 /*
    10.1--- a/sys/src/9/mtx/main.c
    10.2+++ b/sys/src/9/mtx/main.c
    10.3@@ -211,42 +211,12 @@ userinit(void)
    10.4 void
    10.5 reboot(void*, void*, ulong)
    10.6 {
    10.7-	exit(0);
    10.8 }
    10.9 
   10.10 void
   10.11-exit(int ispanic)
   10.12+exit(int)
   10.13 {
   10.14-	int ms, once;
   10.15-
   10.16-	lock(&active);
   10.17-	if(ispanic)
   10.18-		active.ispanic = ispanic;
   10.19-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   10.20-		active.ispanic = 0;
   10.21-	once = active.machs & (1<<m->machno);
   10.22-	active.machs &= ~(1<<m->machno);
   10.23-	active.exiting = 1;
   10.24-	unlock(&active);
   10.25-
   10.26-	if(once)
   10.27-		print("cpu%d: exiting\n", m->machno);
   10.28-	spllo();
   10.29-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   10.30-		delay(TK2MS(2));
   10.31-		if(active.machs == 0 && consactive() == 0)
   10.32-			break;
   10.33-	}
   10.34-
   10.35-	if(active.ispanic && m->machno == 0){
   10.36-		if(cpuserver)
   10.37-			delay(10000);
   10.38-		else if(conf.monitor)
   10.39-			for(;;);
   10.40-	}
   10.41-	else
   10.42-		delay(1000);
   10.43-
   10.44+	cpushutdown();
   10.45 	watchreset();
   10.46 }
   10.47 
    11.1--- a/sys/src/9/omap/dat.h
    11.2+++ b/sys/src/9/omap/dat.h
    11.3@@ -218,7 +218,6 @@ struct
    11.4 	Lock;
    11.5 	int	machs;			/* bitmap of active CPUs */
    11.6 	int	exiting;		/* shutdown */
    11.7-	int	ispanic;		/* shutdown in response to a panic */
    11.8 }active;
    11.9 
   11.10 extern register Mach* m;			/* R10 */
    12.1--- a/sys/src/9/omap/main.c
    12.2+++ b/sys/src/9/omap/main.c
    12.3@@ -301,39 +301,13 @@ machinit(void)
    12.4 	up = nil;
    12.5 }
    12.6 
    12.7-static void
    12.8-shutdown(int ispanic)
    12.9-{
   12.10-	int ms, once;
   12.11-
   12.12-	lock(&active);
   12.13-	if(ispanic)
   12.14-		active.ispanic = ispanic;
   12.15-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   12.16-		active.ispanic = 0;
   12.17-	once = active.machs & (1<<m->machno);
   12.18-	active.machs &= ~(1<<m->machno);
   12.19-	active.exiting = 1;
   12.20-	unlock(&active);
   12.21-
   12.22-	if(once)
   12.23-		iprint("cpu%d: exiting\n", m->machno);
   12.24-	spllo();
   12.25-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   12.26-		delay(TK2MS(2));
   12.27-		if(active.machs == 0 && consactive() == 0)
   12.28-			break;
   12.29-	}
   12.30-	delay(1000);
   12.31-}
   12.32-
   12.33 /*
   12.34  *  exit kernel either on a panic or user request
   12.35  */
   12.36 void
   12.37-exit(int code)
   12.38+exit(int)
   12.39 {
   12.40-	shutdown(code);
   12.41+	cpushutdown();
   12.42 	splhi();
   12.43 	archreboot();
   12.44 }
   12.45@@ -380,17 +354,8 @@ reboot(void *entry, void *code, ulong si
   12.46 {
   12.47 	void (*f)(ulong, ulong, ulong);
   12.48 
   12.49-	print("starting reboot...");
   12.50 	writeconf();
   12.51-	shutdown(0);
   12.52-
   12.53-	/*
   12.54-	 * should be the only processor running now
   12.55-	 */
   12.56-
   12.57-	print("reboot entry %#lux code %#lux size %ld\n",
   12.58-		PADDR(entry), PADDR(code), size);
   12.59-	delay(100);
   12.60+	cpushutdown();
   12.61 
   12.62 	/* turn off buffered serial console */
   12.63 	serialoq = nil;
   12.64@@ -414,10 +379,6 @@ reboot(void *entry, void *code, ulong si
   12.65 
   12.66 	/* off we go - never to return */
   12.67 	(*f)(PADDR(entry), PADDR(code), size);
   12.68-
   12.69-	iprint("loaded kernel returned!\n");
   12.70-	delay(1000);
   12.71-	archreboot();
   12.72 }
   12.73 
   12.74 /*
    13.1--- a/sys/src/9/omap4/dat.h
    13.2+++ b/sys/src/9/omap4/dat.h
    13.3@@ -132,7 +132,6 @@ struct
    13.4 	Lock;
    13.5 	int	machs;			/* bitmap of active CPUs */
    13.6 	int	exiting;		/* shutdown */
    13.7-	int	ispanic;		/* shutdown in response to a panic */
    13.8 }active;
    13.9 
   13.10 extern Mach *m;
    14.1--- a/sys/src/9/pc/dat.h
    14.2+++ b/sys/src/9/pc/dat.h
    14.3@@ -272,7 +272,6 @@ struct
    14.4 	Lock;
    14.5 	int	machs;			/* bitmap of active CPUs */
    14.6 	int	exiting;		/* shutdown */
    14.7-	int	ispanic;		/* shutdown in response to a panic */
    14.8 	int	thunderbirdsarego;	/* lets the added processors continue to schedinit */
    14.9 }active;
   14.10 
    15.1--- a/sys/src/9/pc/main.c
    15.2+++ b/sys/src/9/pc/main.c
    15.3@@ -163,7 +163,6 @@ main(void)
    15.4 		pcimatch(0, 0, 0);
    15.5 	}else
    15.6 		links();
    15.7-	conf.monitor = 1;
    15.8 	chandevreset();
    15.9 	pageinit();
   15.10 	swapinit();
   15.11@@ -890,50 +889,6 @@ procsave(Proc *p)
   15.12 	mmuflushtlb(PADDR(m->pdb));
   15.13 }
   15.14 
   15.15-static void
   15.16-shutdown(int ispanic)
   15.17-{
   15.18-	int ms, once;
   15.19-
   15.20-	lock(&active);
   15.21-	if(ispanic)
   15.22-		active.ispanic = ispanic;
   15.23-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   15.24-		active.ispanic = 0;
   15.25-	once = active.machs & (1<<m->machno);
   15.26-	/*
   15.27-	 * setting exiting will make hzclock() on each processor call exit(0),
   15.28-	 * which calls shutdown(0) and arch->reset(), which on mp systems calls
   15.29-	 * mpshutdown(), from which there is no return: the processor is idled
   15.30-	 * or initiates a reboot.  clearing our bit in machs avoids calling
   15.31-	 * exit(0) from hzclock() on this processor.
   15.32-	 */
   15.33-	active.machs &= ~(1<<m->machno);
   15.34-	active.exiting = 1;
   15.35-	unlock(&active);
   15.36-
   15.37-	if(once)
   15.38-		iprint("cpu%d: exiting\n", m->machno);
   15.39-
   15.40-	/* wait for any other processors to shutdown */
   15.41-	spllo();
   15.42-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   15.43-		delay(TK2MS(2));
   15.44-		if(active.machs == 0 && consactive() == 0)
   15.45-			break;
   15.46-	}
   15.47-
   15.48-	if(active.ispanic){
   15.49-		if(!cpuserver)
   15.50-			for(;;)
   15.51-				halt();
   15.52-		if(getconf("*debug"))
   15.53-			delay(5*60*1000);
   15.54-		else
   15.55-			delay(10000);
   15.56-	}
   15.57-}
   15.58-
   15.59 void
   15.60 reboot(void *entry, void *code, ulong size)
   15.61 {
   15.62@@ -952,10 +907,7 @@ reboot(void *entry, void *code, ulong si
   15.63 		procwired(up, 0);
   15.64 		sched();
   15.65 	}
   15.66-	shutdown(0);
   15.67-
   15.68-	iprint("shutting down...\n");
   15.69-	delay(200);
   15.70+	cpushutdown();
   15.71 
   15.72 	splhi();
   15.73 
   15.74@@ -985,8 +937,8 @@ reboot(void *entry, void *code, ulong si
   15.75 
   15.76 
   15.77 void
   15.78-exit(int ispanic)
   15.79+exit(int)
   15.80 {
   15.81-	shutdown(ispanic);
   15.82+	cpushutdown();
   15.83 	arch->reset();
   15.84 }
    16.1--- a/sys/src/9/pc/screen.c
    16.2+++ b/sys/src/9/pc/screen.c
    16.3@@ -664,6 +664,8 @@ bootscreeninit(void)
    16.4 	scr->cur = &swcursor;
    16.5 	scr->cur->enable(scr);
    16.6 	cursoron();
    16.7+
    16.8+	conf.monitor = 1;
    16.9 }
   16.10 
   16.11 /*
    17.1--- a/sys/src/9/pc64/dat.h
    17.2+++ b/sys/src/9/pc64/dat.h
    17.3@@ -235,7 +235,6 @@ struct
    17.4 	Lock;
    17.5 	int	machs;			/* bitmap of active CPUs */
    17.6 	int	exiting;		/* shutdown */
    17.7-	int	ispanic;		/* shutdown in response to a panic */
    17.8 	int	thunderbirdsarego;	/* lets the added processors continue to schedinit */
    17.9 }active;
   17.10 
    18.1--- a/sys/src/9/pc64/main.c
    18.2+++ b/sys/src/9/pc64/main.c
    18.3@@ -512,7 +512,6 @@ main()
    18.4 		pcimatch(0, 0, 0);
    18.5 	}else
    18.6 		links();
    18.7-	conf.monitor = 1;
    18.8 	chandevreset();
    18.9 	preallocpages();
   18.10 	pageinit();
   18.11@@ -522,54 +521,10 @@ main()
   18.12 	schedinit();
   18.13 }
   18.14 
   18.15-static void
   18.16-shutdown(int ispanic)
   18.17+void
   18.18+exit(int)
   18.19 {
   18.20-	int ms, once;
   18.21-
   18.22-	lock(&active);
   18.23-	if(ispanic)
   18.24-		active.ispanic = ispanic;
   18.25-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   18.26-		active.ispanic = 0;
   18.27-	once = active.machs & (1<<m->machno);
   18.28-	/*
   18.29-	 * setting exiting will make hzclock() on each processor call exit(0),
   18.30-	 * which calls shutdown(0) and arch->reset(), which on mp systems calls
   18.31-	 * mpshutdown(), from which there is no return: the processor is idled
   18.32-	 * or initiates a reboot.  clearing our bit in machs avoids calling
   18.33-	 * exit(0) from hzclock() on this processor.
   18.34-	 */
   18.35-	active.machs &= ~(1<<m->machno);
   18.36-	active.exiting = 1;
   18.37-	unlock(&active);
   18.38-
   18.39-	if(once)
   18.40-		iprint("cpu%d: exiting\n", m->machno);
   18.41-
   18.42-	/* wait for any other processors to shutdown */
   18.43-	spllo();
   18.44-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   18.45-		delay(TK2MS(2));
   18.46-		if(active.machs == 0 && consactive() == 0)
   18.47-			break;
   18.48-	}
   18.49-
   18.50-	if(active.ispanic){
   18.51-		if(!cpuserver)
   18.52-			for(;;)
   18.53-				halt();
   18.54-		if(getconf("*debug"))
   18.55-			delay(5*60*1000);
   18.56-		else
   18.57-			delay(10000);
   18.58-	}
   18.59-}
   18.60-
   18.61-void
   18.62-exit(int ispanic)
   18.63-{
   18.64-	shutdown(ispanic);
   18.65+	cpushutdown();
   18.66 	arch->reset();
   18.67 }
   18.68 
   18.69@@ -590,10 +545,7 @@ reboot(void *entry, void *code, ulong si
   18.70 		procwired(up, 0);
   18.71 		sched();
   18.72 	}
   18.73-	shutdown(0);
   18.74-
   18.75-	iprint("shutting down...\n");
   18.76-	delay(200);
   18.77+	cpushutdown();
   18.78 
   18.79 	splhi();
   18.80 
    19.1--- a/sys/src/9/port/allocb.c
    19.2+++ b/sys/src/9/port/allocb.c
    19.3@@ -86,10 +86,8 @@ iallocb(int size)
    19.4 
    19.5 	if(ialloc.bytes > conf.ialloc){
    19.6 		if((m1++%10000)==0){
    19.7-			if(mp++ > 1000){
    19.8-				active.exiting = 1;
    19.9-				exit(0);
   19.10-			}
   19.11+			if(mp++ > 1000)
   19.12+				panic("iallocb: out of memory");
   19.13 			iprint("iallocb: limited %lud/%lud\n",
   19.14 				ialloc.bytes, conf.ialloc);
   19.15 		}
   19.16@@ -98,10 +96,8 @@ iallocb(int size)
   19.17 
   19.18 	if((b = _allocb(size)) == nil){
   19.19 		if((m2++%10000)==0){
   19.20-			if(mp++ > 1000){
   19.21-				active.exiting = 1;
   19.22-				exit(0);
   19.23-			}
   19.24+			if(mp++ > 1000)
   19.25+				panic("iallocb: out of memory");
   19.26 			iprint("iallocb: no memory %lud/%lud\n",
   19.27 				ialloc.bytes, conf.ialloc);
   19.28 		}
    20.1--- a/sys/src/9/port/devcons.c
    20.2+++ b/sys/src/9/port/devcons.c
    20.3@@ -260,9 +260,15 @@ panic(char *fmt, ...)
    20.4 	splx(s);
    20.5 	prflush();
    20.6 	dumpstack();
    20.7-	if(!cpuserver)
    20.8-		for(;;);
    20.9-	exit(1);
   20.10+
   20.11+	/* reboot cpu servers and headless machines when not debugging */
   20.12+	if(getconf("*debug") == nil)
   20.13+	if(cpuserver || !conf.monitor)
   20.14+		exit(1);
   20.15+
   20.16+	/* otherwise, just hang */
   20.17+	while(islo()) idlehands();
   20.18+	for(;;);
   20.19 }
   20.20 
   20.21 /* libmp at least contains a few calls to sysfatal; simulate with panic */
   20.22@@ -1038,3 +1044,26 @@ writebintime(char *buf, int n)
   20.23 	}
   20.24 	return n;
   20.25 }
   20.26+
   20.27+void
   20.28+cpushutdown(void)
   20.29+{
   20.30+	int ms, once;
   20.31+
   20.32+	lock(&active);
   20.33+	once = active.machs & (1<<m->machno);
   20.34+	active.machs &= ~(1<<m->machno);
   20.35+	active.exiting = 1;
   20.36+	unlock(&active);
   20.37+
   20.38+	if(once)
   20.39+		iprint("cpu%d: exiting\n", m->machno);
   20.40+
   20.41+	/* wait for any other processors to shutdown */
   20.42+	spllo();
   20.43+	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   20.44+		delay(TK2MS(2));
   20.45+		if(active.machs == 0 && consactive() == 0)
   20.46+			break;
   20.47+	}
   20.48+}
    21.1--- a/sys/src/9/port/portfns.h
    21.2+++ b/sys/src/9/port/portfns.h
    21.3@@ -41,6 +41,7 @@ int		cmount(Chan**, Chan*, int, char*);
    21.4 void		confinit(void);
    21.5 int		consactive(void);
    21.6 void		(*consdebug)(void);
    21.7+void		cpushutdown(void);
    21.8 void		copen(Chan*);
    21.9 void		cclunk(Chan*);
   21.10 Block*		concatblock(Block*);
    22.1--- a/sys/src/9/port/rebootcmd.c
    22.2+++ b/sys/src/9/port/rebootcmd.c
    22.3@@ -103,6 +103,5 @@ rebootcmd(int argc, char *argv[])
    22.4 	setbootcmd(argc-1, argv+1);
    22.5 
    22.6 	reboot((void*)entry, p, size);
    22.7-
    22.8-	panic("return from reboot!");
    22.9+	error(Egreg);
   22.10 }
    23.1--- a/sys/src/9/port/ucallocb.c
    23.2+++ b/sys/src/9/port/ucallocb.c
    23.3@@ -78,24 +78,10 @@ uciallocb(int size)
    23.4 	Block *b;
    23.5 	static int m1, m2, mp;
    23.6 
    23.7-	if(0 && ucialloc.bytes > conf.ialloc){
    23.8-		if((m1++%10000)==0){
    23.9-			if(mp++ > 1000){
   23.10-				active.exiting = 1;
   23.11-				exit(0);
   23.12-			}
   23.13-			iprint("uciallocb: limited %lud/%lud\n",
   23.14-				ucialloc.bytes, conf.ialloc);
   23.15-		}
   23.16-		return nil;
   23.17-	}
   23.18-
   23.19 	if((b = _ucallocb(size)) == nil){
   23.20 		if(0 && (m2++%10000)==0){
   23.21-			if(mp++ > 1000){
   23.22-				active.exiting = 1;
   23.23-				exit(0);
   23.24-			}
   23.25+			if(mp++ > 1000)
   23.26+				panic("uciallocb: out of memory");
   23.27 			iprint("uciallocb: no memory %lud/%lud\n",
   23.28 				ucialloc.bytes, conf.ialloc);
   23.29 		}
    24.1--- a/sys/src/9/ppc/dat.h
    24.2+++ b/sys/src/9/ppc/dat.h
    24.3@@ -191,7 +191,6 @@ struct
    24.4 	Lock;
    24.5 	short	machs;
    24.6 	short	exiting;
    24.7-	short	ispanic;
    24.8 }active;
    24.9 
   24.10 /*
    25.1--- a/sys/src/9/ppc/main.c
    25.2+++ b/sys/src/9/ppc/main.c
    25.3@@ -243,38 +243,10 @@ userinit(void)
    25.4 }
    25.5 
    25.6 void
    25.7-exit(int ispanic)
    25.8+exit(int)
    25.9 {
   25.10-	int ms, once;
   25.11-
   25.12-	lock(&active);
   25.13-	if(ispanic)
   25.14-		active.ispanic = ispanic;
   25.15-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   25.16-		active.ispanic = 0;
   25.17-	once = active.machs & (1<<m->machno);
   25.18-	active.machs &= ~(1<<m->machno);
   25.19-	active.exiting = 1;
   25.20-	unlock(&active);
   25.21-
   25.22-	if(once)
   25.23-		print("cpu%d: exiting\n", m->machno);
   25.24-	spllo();
   25.25-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   25.26-		delay(TK2MS(2));
   25.27-		if(active.machs == 0 && consactive() == 0)
   25.28-			break;
   25.29-	}
   25.30-
   25.31-	if(active.ispanic && m->machno == 0){
   25.32-		if(cpuserver)
   25.33-			delay(10000);
   25.34-		else if(conf.monitor)
   25.35-			for(;;);
   25.36-	}
   25.37-	else
   25.38-		delay(1000);
   25.39-
   25.40+	cpushutdown();
   25.41+	for(;;) idlehands();
   25.42 }
   25.43 
   25.44 /*
   25.45@@ -424,8 +396,6 @@ confinit(void)
   25.46 		 */
   25.47 		imagmem->maxsize = kpages;
   25.48 	}
   25.49-
   25.50-//	conf.monitor = 1;	/* BUG */
   25.51 }
   25.52 
   25.53 static int
    26.1--- a/sys/src/9/sgi/dat.h
    26.2+++ b/sys/src/9/sgi/dat.h
    26.3@@ -206,7 +206,6 @@ struct
    26.4 	Lock;
    26.5 	long	machs;		/* bitmap of processors */
    26.6 	short	exiting;
    26.7-	int	ispanic;
    26.8 }active;
    26.9 
   26.10 extern register Mach	*m;
    27.1--- a/sys/src/9/sgi/main.c
    27.2+++ b/sys/src/9/sgi/main.c
    27.3@@ -372,10 +372,10 @@ userinit(void)
    27.4 }
    27.5 
    27.6 void
    27.7-exit(int ispanic)
    27.8+exit(int)
    27.9 {
   27.10+	cpushutdown();
   27.11 	splhi();
   27.12-	while(ispanic);
   27.13 	arcs(0x18);	/* reboot */
   27.14 }
   27.15 
    28.1--- a/sys/src/9/teg2/dat.h
    28.2+++ b/sys/src/9/teg2/dat.h
    28.3@@ -250,7 +250,6 @@ struct
    28.4 	int	wfi;			/* bitmap of CPUs in WFI state */
    28.5 	int	stopped;		/* bitmap of CPUs stopped */
    28.6 	int	exiting;		/* shutdown */
    28.7-	int	ispanic;		/* shutdown in response to a panic */
    28.8 	int	thunderbirdsarego;	/* lets the added processors continue to schedinit */
    28.9 }active;
   28.10 
    29.1--- a/sys/src/9/teg2/main.c
    29.2+++ b/sys/src/9/teg2/main.c
    29.3@@ -480,51 +480,13 @@ main(void)
    29.4 	panic("cpu%d: schedinit returned", m->machno);
    29.5 }
    29.6 
    29.7-static void
    29.8-shutdown(int ispanic)
    29.9-{
   29.10-	int ms, once;
   29.11-
   29.12-	lock(&active);
   29.13-	if(ispanic)
   29.14-		active.ispanic = ispanic;
   29.15-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   29.16-		active.ispanic = 0;
   29.17-	once = active.machs & (1<<m->machno);
   29.18-	/*
   29.19-	 * setting exiting will make hzclock() on each processor call exit(0),
   29.20-	 * which calls shutdown(0) and idles non-bootstrap cpus and returns
   29.21-	 * on bootstrap processors (to permit a reboot).  clearing our bit
   29.22-	 * in machs avoids calling exit(0) from hzclock() on this processor.
   29.23-	 */
   29.24-	active.machs &= ~(1<<m->machno);
   29.25-	active.exiting = 1;
   29.26-	unlock(&active);
   29.27-
   29.28-	if(once) {
   29.29-		delay(m->machno*1000);		/* stagger them */
   29.30-		iprint("cpu%d: exiting\n", m->machno);
   29.31-	}
   29.32-	spllo();
   29.33-	if (m->machno == 0)
   29.34-		ms = 5*1000;
   29.35-	else
   29.36-		ms = 2*1000;
   29.37-	for(; ms > 0; ms -= TK2MS(2)){
   29.38-		delay(TK2MS(2));
   29.39-		if(active.machs == 0 && consactive() == 0)
   29.40-			break;
   29.41-	}
   29.42-	delay(500);
   29.43-}
   29.44-
   29.45 /*
   29.46  *  exit kernel either on a panic or user request
   29.47  */
   29.48 void
   29.49-exit(int code)
   29.50+exit(int)
   29.51 {
   29.52-	shutdown(code);
   29.53+	cpushutdown();
   29.54 	splhi();
   29.55 	if (m->machno == 0)
   29.56 		archreboot();
   29.57@@ -576,10 +538,8 @@ isaconfig(char *class, int ctlrno, ISACo
   29.58 void
   29.59 reboot(void *entry, void *code, ulong size)
   29.60 {
   29.61-	int cpu, nmach, want, ms;
   29.62 	void (*f)(ulong, ulong, ulong);
   29.63 
   29.64-	nmach = conf.nmach;
   29.65 	writeconf();
   29.66 
   29.67 	/*
   29.68@@ -590,33 +550,12 @@ reboot(void *entry, void *code, ulong si
   29.69 		procwired(up, 0);
   29.70 		sched();
   29.71 	}
   29.72-	if (m->machno != 0)
   29.73-		print("on cpu%d (not 0)!\n", m->machno);
   29.74-
   29.75-	/*
   29.76-	 * the other cpus could be holding locks that will never get
   29.77-	 * released (e.g., in the print path) if we put them into
   29.78-	 * reset now, so force them to shutdown gracefully first.
   29.79-	 */
   29.80-	for (want = 0, cpu = 1; cpu < navailcpus; cpu++)
   29.81-		want |= 1 << cpu;
   29.82-	active.stopped = 0;
   29.83-	shutdown(0);
   29.84-	for (ms = 15*1000; ms > 0 && active.stopped != want; ms -= 10)
   29.85-		delay(10);
   29.86-	delay(20);
   29.87-	if (active.stopped != want) {
   29.88-		for (cpu = 1; cpu < nmach; cpu++)
   29.89-			stopcpu(cpu);		/* make really sure */
   29.90-		delay(20);
   29.91-	}
   29.92+	cpushutdown();
   29.93 
   29.94 	/*
   29.95 	 * should be the only processor running now
   29.96 	 */
   29.97 	pcireset();
   29.98-//	print("reboot entry %#lux code %#lux size %ld\n",
   29.99-//		PADDR(entry), PADDR(code), size);
  29.100 
  29.101 	/* turn off buffered serial console */
  29.102 	serialoq = nil;
  29.103@@ -642,9 +581,6 @@ reboot(void *entry, void *code, ulong si
  29.104 
  29.105 	/* off we go - never to return */
  29.106 	(*f)(PADDR(entry), PADDR(code), size);
  29.107-
  29.108-	iprint("loaded kernel returned!\n");
  29.109-	archreboot();
  29.110 }
  29.111 
  29.112 /*
    30.1--- a/sys/src/9/xen/main.c
    30.2+++ b/sys/src/9/xen/main.c
    30.3@@ -644,58 +644,13 @@ procsave(Proc *p)
    30.4 	mmuflushtlb(0);
    30.5 }
    30.6 
    30.7-static void
    30.8-shutdown(int ispanic)
    30.9-{
   30.10-	int ms, once;
   30.11-
   30.12-	lock(&active);
   30.13-	if(ispanic)
   30.14-		active.ispanic = ispanic;
   30.15-	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
   30.16-		active.ispanic = 0;
   30.17-	once = active.machs & (1<<m->machno);
   30.18-	active.machs &= ~(1<<m->machno);
   30.19-	active.exiting = 1;
   30.20-	unlock(&active);
   30.21-
   30.22-	if(once)
   30.23-		print("cpu%d: exiting\n", m->machno);
   30.24-	//spllo();
   30.25-	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
   30.26-		delay(TK2MS(2));
   30.27-		if(active.machs == 0 && consactive() == 0)
   30.28-			break;
   30.29-	}
   30.30-
   30.31-	if(getconf("*debug"))
   30.32-		delay(5*60*1000);
   30.33-
   30.34-	if(active.ispanic){
   30.35-		if(!cpuserver)
   30.36-			for(;;)
   30.37-				halt();
   30.38-		delay(10000);
   30.39-	}else
   30.40-		delay(1000);
   30.41-}
   30.42-
   30.43 void
   30.44 reboot(void *entry, void *code, ulong size)
   30.45 {
   30.46 	void (*f)(ulong, ulong, ulong);
   30.47-	//ulong *pdb;
   30.48 
   30.49 	writeconf();
   30.50-
   30.51-	shutdown(0);
   30.52-
   30.53-	/*
   30.54-	 * should be the only processor running now
   30.55-	 */
   30.56-
   30.57-	print("shutting down...\n");
   30.58-	delay(200);
   30.59+	cpushutdown();
   30.60 
   30.61 	splhi();
   30.62 
   30.63@@ -709,28 +664,19 @@ reboot(void *entry, void *code, ulong si
   30.64 	if(entry == 0)
   30.65 		HYPERVISOR_shutdown(0);
   30.66 
   30.67-	/*
   30.68-	 * Modify the machine page table to directly map the low 4MB of memory
   30.69-	 * This allows the reboot code to turn off the page mapping
   30.70-	 */
   30.71-	//pdb = m->pdb;
   30.72-	//pdb[PDX(0)] = pdb[PDX(KZERO)];
   30.73 	mmuflushtlb(0);
   30.74 
   30.75 	/* setup reboot trampoline function */
   30.76 	f = (void*)REBOOTADDR;
   30.77 	memmove(f, rebootcode, sizeof(rebootcode));
   30.78 
   30.79-	print("rebooting...\n");
   30.80-
   30.81 	/* off we go - never to return */
   30.82 	(*f)(PADDR(entry), PADDR(code), size);
   30.83 }
   30.84 
   30.85-
   30.86 void
   30.87-exit(int ispanic)
   30.88+exit(int)
   30.89 {
   30.90-	shutdown(ispanic);
   30.91+	cpushutdown();
   30.92 	arch->reset();
   30.93 }
    31.1--- a/sys/src/9/zynq/dat.h
    31.2+++ b/sys/src/9/zynq/dat.h
    31.3@@ -177,7 +177,6 @@ struct
    31.4 	Lock;
    31.5 	int	machs;			/* bitmap of active CPUs */
    31.6 	int	exiting;		/* shutdown */
    31.7-	int	ispanic;		/* shutdown in response to a panic */
    31.8 }active;
    31.9 
   31.10 extern register Mach* m;			/* R10 */
    32.1--- a/sys/src/9/zynq/main.c
    32.2+++ b/sys/src/9/zynq/main.c
    32.3@@ -21,13 +21,13 @@ int nconf;
    32.4 void
    32.5 exit(int)
    32.6 {
    32.7-	NOPE
    32.8+	cpushutdown();
    32.9+	for(;;) idlehands();
   32.10 }
   32.11 
   32.12 void
   32.13 reboot(void *, void *, ulong)
   32.14 {
   32.15-	NOPE
   32.16 }
   32.17 
   32.18 void