--- /n/sources/plan9/sys/src/9/pc/dat.h Thu Jun 13 21:02:15 2013 +++ /sys/src/9/pc/dat.h Tue Jan 5 00:00:00 2016 @@ -282,7 +282,11 @@ struct { Lock; - int machs; /* bitmap of active CPUs */ + union { + uvlong machs; /* bitmap of active CPUs */ + ulong machsmap[(MAXMACH+BI2WD-1)/BI2WD]; + }; + int nmachs; /* number of bits set in machs(map) */ int exiting; /* shutdown */ int ispanic; /* shutdown in response to a panic */ int thunderbirdsarego; /* lets the added processors continue to schedinit */ diff -Nru /n/sources/plan9/sys/src/9/pc/main.c /sys/src/9/pc/main.c --- /n/sources/plan9/sys/src/9/pc/main.c Tue Mar 11 19:49:31 2014 +++ /sys/src/9/pc/main.c Tue Jan 5 00:00:00 2016 @@ -180,7 +180,7 @@ machinit(); - active.machs = 1; + cpuactive(0); active.exiting = 0; } @@ -762,9 +762,9 @@ lock(&active); if(ispanic) active.ispanic = ispanic; - else if(m->machno == 0 && (active.machs & (1<machno)) == 0) + else if(m->machno == 0 && !iscpuactive(m->machno)) active.ispanic = 0; - once = active.machs & (1<machno); + once = iscpuactive(m->machno); /* * setting exiting will make hzclock() on each processor call exit(0), * which calls shutdown(0) and arch->reset(), which on mp systems is @@ -772,7 +772,7 @@ * processors (to permit a reboot). clearing our bit in machs avoids * calling exit(0) from hzclock() on this processor. */ - active.machs &= ~(1<machno); + cpuinactive(m->machno); active.exiting = 1; unlock(&active); @@ -783,7 +783,7 @@ spllo(); for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ delay(TK2MS(2)); - if(active.machs == 0 && consactive() == 0) + if(active.nmachs == 0 && consactive() == 0) break; } @@ -836,7 +836,8 @@ /* * should be the only processor running now */ - active.machs = 0; + memset(active.machsmap, 0, sizeof active.machsmap); + active.nmachs = 0; if (m->machno != 0) print("on cpu%d (not 0)!\n", m->machno); --- /n/sources/plan9/sys/src/9/pc/mem.h Wed Feb 13 21:05:28 2013 +++ /sys/src/9/pc/mem.h Tue Jan 5 00:00:00 2016 @@ -18,11 +18,11 @@ #define FPalign 16 /* required for FXSAVE */ /* - * In 32-bit mode, the MAXMACH limit is 32 without - * changing the way active.machs is defined and used - * (unfortunately, it is also used in the port code). + * Must define MACHS_BITMAP in ports that support MAXMACH > 64; + * optional otherwise. */ -#define MAXMACH 32 /* max # cpus system can run */ +#define MAXMACH 64 /* max # cpus system can run */ +#define MACHS_BITMAP #define KSTACK 4096 /* Size of kernel stack */ /* --- /n/sources/plan9/sys/src/9/pc/mmu.c Wed Aug 15 19:12:32 2012 +++ /sys/src/9/pc/mmu.c Tue Jan 5 00:00:00 2016 @@ -680,7 +680,7 @@ for(i=0; imachno) { nm = MACHP(i); - while((active.machs&(1<machno)) && nm->flushmmu) + while(iscpuactive(nm->machno) && nm->flushmmu) ; } } --- /n/sources/plan9/sys/src/9/pc/mp.c Thu Jun 13 21:01:42 2013 +++ /sys/src/9/pc/mp.c Tue Jan 5 00:00:00 2016 @@ -417,7 +417,7 @@ fpoff(); lock(&active); - active.machs |= 1<machno; + cpuactive(m->machno); unlock(&active); while(!active.thunderbirdsarego) @@ -920,7 +920,7 @@ if(active.rebooting) return; - print("apshutdown: active = %#8.8ux\n", active.machs); + print("apshutdown: %d active cpus\n", active.nmachs); delay(1000); splhi(); arch->resetothers(); diff -Nru /n/sources/plan9/sys/src/9/pc/trap.c /sys/src/9/pc/trap.c --- /n/sources/plan9/sys/src/9/pc/trap.c Wed May 14 14:45:00 2014 +++ /sys/src/9/pc/trap.c Tue Jan 5 00:00:00 2016 @@ -397,8 +397,8 @@ if(0)print("cpu%d: spurious interrupt %d, last %d\n", m->machno, vno, m->lastintr); if(0)if(conf.nmach > 1){ - for(i = 0; i < 32; i++){ - if(!(active.machs & (1<machno == mach->machno) --- /n/sources/plan9/sys/src/9/port/devcons.c Fri Jul 19 06:22:41 2013 +++ /sys/src/9/port/devcons.c Tue Jan 5 00:00:00 2016 @@ -872,7 +872,7 @@ b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1); /* +1 for NUL */ bp = b; - for(id = 0; id < 32; id++) { + for(id = 0; id < MAXMACH; id++) { - if(active.machs & (1<cs = 0; mp->intr = 0; --- /n/sources/plan9/sys/src/9/port/portclock.c Sat Apr 28 03:46:42 2012 +++ /sys/src/9/port/portclock.c Tue Jan 5 00:00:00 2016 @@ -151,7 +151,7 @@ if(kproftimer != nil) kproftimer(ur->pc); - if((active.machs&(1<machno)) == 0) + if(!iscpuactive(m->machno)) return; if(active.exiting) { --- /n/sources/plan9/sys/src/9/port/portfns.h Tue Mar 11 19:44:26 2014 +++ /sys/src/9/port/portfns.h Tue Jan 5 00:00:00 2016 @@ -48,6 +48,8 @@ Block* copyblock(Block*, int); void copypage(Page*, Page*); void countpagerefs(ulong*, int); +void cpuactive(uint); +void cpuinactive(uint); int cread(Chan*, uchar*, int, vlong); void cunmount(Chan*, Chan*); void cupdate(Chan*, uchar*, int, vlong); @@ -137,6 +139,7 @@ void initmark(Watermark *, int, char *); void initseg(void); int iprint(char*, ...); +int iscpuactive(uint); void isdir(Chan*); int iseve(void); int islo(void); --- /n/sources/plan9/sys/src/9/port/proc.c Mon Dec 2 22:42:53 2013 +++ /sys/src/9/port/proc.c Tue Jan 5 00:00:00 2016 @@ -581,6 +581,43 @@ return ok; } +/* + * these assume that active.Lock is held when needed. + */ + +void +cpuactive(uint cpu) +{ +#ifdef MACHS_BITMAP + active.machsmap[cpu / BI2WD] |= 1ULL << (cpu % BI2WD); + active.nmachs++; +#else + active.machs |= 1ULL << cpu; +#endif +} + +void +cpuinactive(uint cpu) +{ +#ifdef MACHS_BITMAP + active.machsmap[cpu / BI2WD] &= ~(1ULL << (cpu % BI2WD)); + active.nmachs--; +#else + active.machs &= ~(1ULL << cpu); +#endif +} + +int +iscpuactive(uint cpu) +{ +#ifdef MACHS_BITMAP + return (active.machsmap[cpu / BI2WD] & (1ULL << (cpu % BI2WD))) != 0; +#else + return (active.machs & (1ULL << cpu)) != 0; +#endif +} + + void noprocpanic(char *msg) { @@ -590,7 +627,7 @@ * on this processor. */ lock(&active); - active.machs &= ~(1<machno); + cpuinactive(m->machno); active.exiting = 1; unlock(&active);