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; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
/n/sourcesdump/2005/1109/plan9/sys/src/9/port/page.c:44,50 -
/n/sourcesdump/2005/1110/plan9/sys/src/9/port/page.c:45,51
palloc.head->prev = 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; i<np; i++){
+ if(palloc.pages[i].ref != ref[i]){
+ iprint("page %#.8lux ref %d actual %lud\n",
+ palloc.pages[i].pa, palloc.pages[i].ref, ref[i]);
+ ref[i] = 1;
+ nwrong++;
+ }else
+ ref[i] = 0;
+ }
+ countpagerefs(ref, 1);
+ portcountpagerefs(ref, 1);
+ iprint("%lud mistakes found\n", nwrong);
+ unlock(&palloc);
+ splx(s);
+ }
+
+ void
+ portcountpagerefs(ulong *ref, int print)
+ {
+ ulong i, j, k, ns, n;
+ Page **pg, *entry;
+ Proc *p;
+ Pte *pte;
+ Segment *s;
+
+ /*
+ * Pages in segments. s->mark avoids double-counting.
+ */
+ n = 0;
+ ns = 0;
+ for(i=0; i<conf.nproc; i++){
+ p = proctab(i);
+ for(j=0; j<NSEG; j++){
+ s = p->seg[j];
+ if(s)
+ s->mark = 0;
+ }
+ }
+ for(i=0; i<conf.nproc; i++){
+ p = proctab(i);
+ for(j=0; j<NSEG; j++){
+ s = p->seg[j];
+ if(s == nil || s->mark++)
+ continue;
+ ns++;
+ for(k=0; k<s->mapsize; 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; i<conf.nproc; i++){
+ p = proctab(i);
+ for(j=0; j<NSEG; j++){
+ s = p->seg[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;
|