Various debugging. [rsc] --rw-rw-r-- M 4315 glenda sys 6554 Nov 9 06:54 sys/src/9/pc/dat.h /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/dat.h:111,117 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/dat.h:111,119 Page* mmupdb; /* page directory base */ Page* mmufree; /* unused page table pages */ Page* mmuused; /* used page table pages */ + Page* kmaptable; /* page table used by kmap */ uint lastkmap; /* last entry used by kmap */ + int nkmap; /* number of current kmaps */ }; /* [rsc] --rw-rw-r-- M 4315 glenda sys 23004 Nov 9 06:54 sys/src/9/port/devcons.c /n/sourcesdump/2005/1109/plan9/sys/src/9/port/devcons.c:227,236 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/devcons.c:227,258 return n; } + /* + * Want to interlock iprints to avoid interlaced output on + * multiprocessor, but don't want to deadlock if one processor + * dies during print and another has something important to say. + * Make a good faith effort. + */ + static Lock iprintlock; + static int + iprintcanlock(Lock *l) + { + int i; + + for(i=0; i<1000; i++){ + if(canlock(l)) + return 1; + if(l->m == MACHP(m->machno)) + return 0; + microdelay(100); + } + return 0; + } + int iprint(char *fmt, ...) { - int n, s; + int n, s, locked; va_list arg; char buf[PRINTSIZE]; /n/sourcesdump/2005/1109/plan9/sys/src/9/port/devcons.c:238,246 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/devcons.c:260,271 va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); + locked = iprintcanlock(&iprintlock); if(screenputs != nil && iprintscreenputs) screenputs(buf, n); uartputs(buf, n); + if(locked) + unlock(&iprintlock); splx(s); return n; [rsc] --rw-rw-r-- M 4315 glenda sys 11124 Nov 9 06:54 sys/src/9/port/page.c /n/sourcesdump/2005/1109/plan9/sys/src/9/port/page.c:22,32 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/page.c:22,33 pm = &palloc.mem[i]; np += pm->npage; } - palloc.head = xalloc(np*sizeof(Page)); - if(palloc.head == 0) + palloc.pages = xalloc(np*sizeof(Page)); + if(palloc.pages == 0) panic("pageinit"); color = 0; + palloc.head = palloc.pages; p = palloc.head; for(i=0; iprev = 0; palloc.tail->next = 0; - palloc.user = p - palloc.head; + palloc.user = p - palloc.pages; pkb = palloc.user*BY2PG/1024; vkb = pkb + (conf.nswap*BY2PG)/1024; /n/sourcesdump/2005/1109/plan9/sys/src/9/port/page.c:323,329 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/page.c:324,340 pageunchain(np); pagechaintail(np); - + /* + * XXX - here's a bug? - np is on the freelist but it's not really free. + * when we unlock palloc someone else can come in, decide to + * use np, and then try to lock it. they succeed after we've + * run copypage and cachepage and unlock(np). then what? + * they call pageunchain before locking(np), so it's removed + * from the freelist, but still in the cache because of + * cachepage below. if someone else looks in the cache + * before they remove it, the page will have a nonzero ref + * once they finally lock(np). + */ lock(np); unlock(&palloc); /n/sourcesdump/2005/1109/plan9/sys/src/9/port/page.c:526,528 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/page.c:537,652 } free(p); } + + ulong + pagenumber(Page *p) + { + return p-palloc.pages; + } + + void + checkpagerefs(void) + { + int s; + ulong i, np, nwrong; + ulong *ref; + + np = palloc.user; + ref = malloc(np*sizeof ref[0]); + if(ref == nil){ + print("checkpagerefs: out of memory\n"); + return; + } + + /* + * This may not be exact if there are other processes + * holding refs to pages on their stacks. The hope is + * that if you run it on a quiescent system it will still + * be useful. + */ + s = splhi(); + lock(&palloc); + countpagerefs(ref, 0); + portcountpagerefs(ref, 0); + nwrong = 0; + for(i=0; imark avoids double-counting. + */ + n = 0; + ns = 0; + for(i=0; iseg[j]; + if(s) + s->mark = 0; + } + } + for(i=0; iseg[j]; + if(s == nil || s->mark++) + continue; + ns++; + for(k=0; kmapsize; k++){ + pte = s->map[k]; + if(pte == nil) + continue; + for(pg = pte->first; pg <= pte->last; pg++){ + entry = *pg; + if(pagedout(entry)) + continue; + if(print){ + if(ref[pagenumber(entry)]) + iprint("page %#.8lux in segment %#p\n", entry->pa, s); + continue; + } + if(ref[pagenumber(entry)]++ == 0) + n++; + } + } + } + } + if(!print){ + iprint("%lud pages in %lud segments\n", n, ns); + for(i=0; iseg[j]; + if(s == nil) + continue; + if(s->ref != s->mark){ + iprint("segment %#.8lux (used by proc %lud pid %lud) has bad ref count %lud actual %lud\n", + s, i, p->pid, s->ref, s->mark); + } + } + } + } + } + [rsc] --rw-rw-r-- M 4315 glenda sys 22702 Nov 9 06:54 sys/src/9/port/portdat.h /n/sourcesdump/2005/1109/plan9/sys/src/9/port/portdat.h:416,421 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/portdat.h:416,422 Pte **map; int mapsize; Pte *ssegmap[SSEGMAPSIZE]; + ulong mark; /* portcountrefs */ }; enum /n/sourcesdump/2005/1109/plan9/sys/src/9/port/portdat.h:494,499 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/portdat.h:495,501 Page *head; /* most recently used */ Page *tail; /* least recently used */ ulong freecount; /* how many pages on free list now */ + Page *pages; /* array of all pages */ ulong user; /* how many user pages */ Page *hash[PGHSIZE]; Lock hashlock; [rsc] --rw-rw-r-- M 4315 glenda sys 11022 Nov 9 06:54 sys/src/9/port/portfns.h /n/sourcesdump/2005/1109/plan9/sys/src/9/port/portfns.h:45,50 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/portfns.h:45,51 Block* concatblock(Block*); Block* copyblock(Block*, int); void copypage(Page*, Page*); + void countpagerefs(ulong*, int); int cread(Chan*, uchar*, int, vlong); void cunmount(Chan*, Chan*); void cupdate(Chan*, uchar*, int, vlong); /n/sourcesdump/2005/1109/plan9/sys/src/9/port/portfns.h:204,209 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/portfns.h:205,211 Block* padblock(Block*, int); void pagechainhead(Page*); void pageinit(void); + ulong pagenumber(Page*); void pagersummary(void); void panic(char*, ...); Cmdbuf* parsecmd(char *a, int n); /n/sourcesdump/2005/1109/plan9/sys/src/9/port/portfns.h:214,219 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/portfns.h:216,222 void pgrpnote(ulong, char*, long, int); void pio(Segment *, ulong, ulong, Page **); #define poperror() up->nerrlab-- + void portcountpagerefs(ulong*, int); int postnote(Proc*, int, char*, int); int pprint(char*, ...); int preempted(void); [rsc] --rw-rw-r-- M 4315 glenda sys 15145 Nov 9 06:54 sys/src/9/port/sysproc.c /n/sourcesdump/2005/1109/plan9/sys/src/9/port/sysproc.c:12,25 - /n/sourcesdump/2005/1110/plan9/sys/src/9/port/sysproc.c:12,23 int shargs(char*, int, char**); extern void checkpages(void); + extern void checkpagerefs(void); long sysr1(ulong*) { - extern int chandebug; - - chandebug = !chandebug; - checkpages(); + checkpagerefs(); return 0; } [rsc] --rw-rw-r-- M 4315 glenda sys 4981 Nov 9 07:14 sys/src/9/alphapc/mmu.c /n/sourcesdump/2005/1109/plan9/sys/src/9/alphapc/mmu.c:278,280 - /n/sourcesdump/2005/1110/plan9/sys/src/9/alphapc/mmu.c:278,284 { } + void + countpagerefs(ulong*, int) + { + } [rsc] --rw-rw-r-- M 4315 glenda bitsy 11298 Nov 9 07:14 sys/src/9/bitsy/mmu.c /n/sourcesdump/2005/1109/plan9/sys/src/9/bitsy/mmu.c:505,508 - /n/sourcesdump/2005/1110/plan9/sys/src/9/bitsy/mmu.c:505,516 } } - void checkmmu(ulong, ulong) { } + void + checkmmu(ulong, ulong) + { + } + + void + countpagerefs(ulong*, int) + { + } [rsc] --rw-rw-r-- M 4315 glenda sys 4458 Nov 9 07:14 sys/src/9/mtx/mmu.c /n/sourcesdump/2005/1109/plan9/sys/src/9/mtx/mmu.c:231,234 - /n/sourcesdump/2005/1110/plan9/sys/src/9/mtx/mmu.c:231,242 } } - void checkmmu(ulong, ulong) { } + void + checkmmu(ulong, ulong) + { + } + + void + countpagerefs(ulong*, int) + { + } [rsc] --rw-rw-r-- M 4315 glenda sys 17317 Nov 9 07:15 sys/src/9/pc/mp.c /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/mp.c:145,151 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/mp.c:145,151 /* * Map the I/O APIC. */ - if((va = vmap(p->addr, 1024)) == 0) + if((va = vmap(p->addr, 1024)) == nil) return 0; apic = &mpapic[p->apicno]; /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/mp.c:152,157 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/mp.c:152,158 apic->type = PcmpIOAPIC; apic->apicno = p->apicno; apic->addr = va; + apic->paddr = p->addr; apic->flags = p->flags; return apic; /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/mp.c:483,488 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/mp.c:484,490 */ if((va = vmap(pcmp->lapicbase, 1024)) == nil) return; + print("LAPIC: %.8lux %.8lux\n", pcmp->lapicbase, (ulong)va); bpapic = nil; /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/mp.c:514,519 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/mp.c:516,522 * first in the table before the others. */ apic->addr = va; + apic->paddr = pcmp->lapicbase; if(apic->flags & PcmpBP) bpapic = apic; } /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/mp.c:667,672 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/mp.c:670,676 vno = lo & 0xFF; n = mpintrinit(bus, aintr->intr, vno, v->irq); n |= ApicLOGICAL; + lo &= ~(ApicRemoteIRR|ApicDELIVS); if(n != lo || !(n & ApicLEVEL)){ print("mpintrenable: multiple botch irq%d, tbdf %uX, lo %8.8uX, n %8.8uX\n", v->irq, tbdf, lo, n); [rsc] --rw-rw-r-- M 4315 glenda sys 6652 Nov 9 07:15 sys/src/9/pc/mp.h /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/mp.h:157,162 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/mp.h:157,163 int type; int apicno; ulong* addr; /* register base address */ + ulong paddr; int flags; /* PcmpBP|PcmpEN */ Lock; /* I/O APIC: register access */ [rsc] --rw-rw-r-- M 4315 glenda sys 55207 Nov 9 07:14 sys/src/9/pc/sd53c8xx.c /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/sd53c8xx.c:2182,2188 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/sd53c8xx.c:2182,2188 /* * Because we don't yet have an abstraction for the * addresses as seen from the controller side (and on - * the 386 it doesn't matter), the follwong two lines + * the 386 it doesn't matter), the following two lines * are different between the 386 and alpha copies of * this driver. */ [rsc] --rw-rw-r-- M 4315 jmk sys 22616 Nov 9 07:16 sys/src/9/pc/ethervt6102.c /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/ethervt6102.c:948,953 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/ethervt6102.c:948,954 default: continue; case (0x3065<<16)|0x1106: /* Rhine II */ + case (0x3106<<16)|0x1106: /* Rhine III */ break; } [rsc] --rw-rw-r-- M 4315 presotto sys 4934 Nov 9 07:14 sys/src/9/ppc/mmu.c /n/sourcesdump/2005/1109/plan9/sys/src/9/ppc/mmu.c:258,261 - /n/sourcesdump/2005/1110/plan9/sys/src/9/ppc/mmu.c:258,269 } - void checkmmu(ulong, ulong) { } + void + checkmmu(ulong, ulong) + { + } + + void + countpagerefs(ulong*, int) + { + } [rsc] --rw-rw-r-- M 4315 glenda sys 18191 Nov 9 16:55 sys/src/9/pc/memory.c /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/memory.c:633,639 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/memory.c:633,640 { int i; Ureg u; - ulong cont, base, last, len; + ulong cont, base, len; + uvlong last; Emap *e; if(getconf("*norealmode") || getconf("*noe820scan")) /n/sourcesdump/2005/1109/plan9/sys/src/9/pc/memory.c:696,702 - /n/sourcesdump/2005/1110/plan9/sys/src/9/pc/memory.c:697,704 else map(base, len, MemReserved); } - + if(last < (1LL<<32)) + map(last, (u32int)-last, MemUPA); return 0; } Snap mouse to border when grabbing to resize. [rsc] --rw-rw-r-- M 4315 glenda sys 22788 Nov 9 16:18 sys/src/cmd/rio/rio.c /n/sourcesdump/2005/1109/plan9/sys/src/cmd/rio/rio.c:887,892 - /n/sourcesdump/2005/1110/plan9/sys/src/cmd/rio/rio.c:887,924 return ni; } + Point + cornerpt(Rectangle r, Point p, int which) + { + switch(which){ + case 0: /* top left */ + p = Pt(r.min.x, r.min.y); + break; + case 2: /* top right */ + p = Pt(r.max.x,r.min.y); + break; + case 6: /* bottom left */ + p = Pt(r.min.x, r.max.y); + break; + case 8: /* bottom right */ + p = Pt(r.max.x, r.max.y); + break; + case 1: /* top edge */ + p = Pt(p.x,r.min.y); + break; + case 5: /* right edge */ + p = Pt(r.max.x, p.y); + break; + case 7: /* bottom edge */ + p = Pt(p.x, r.max.y); + break; + case 3: /* left edge */ + p = Pt(r.min.x, p.y); + break; + } + return p; + } + Rectangle whichrect(Rectangle r, Point p, int which) { /n/sourcesdump/2005/1109/plan9/sys/src/cmd/rio/rio.c:928,935 - /n/sourcesdump/2005/1110/plan9/sys/src/cmd/rio/rio.c:960,970 int which, but; p = mouse->xy; - startp = p; + which = whichcorner(w, p); + startp = cornerpt(w->screenr, p, which); + wmovemouse(w, startp); + readmouse(mousectl); r = whichrect(w->screenr, p, which); drawborder(r, 1); or = r;