From cc5f512f51cb05b4b4d9125887d4c2137612e776 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 10 Jan 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-01-10 --- port/devcons.c | 1 + port/fault.c | 91 ++++++++++++++++++++++---------------------------- port/portdat.h | 2 +- port/portfns.h | 1 + port/proc.c | 4 +-- port/qlock.c | 1 + port/swap.c | 33 ++++++++++-------- 7 files changed, 64 insertions(+), 69 deletions(-) diff --git a/port/devcons.c b/port/devcons.c index 9be7208e902e187d86ae3cd12a4bea13c005a4aa..b09f7d704983057a96f6d0131b54ed001679cae8 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -233,6 +233,7 @@ echo(Rune r, char *buf, int n) xsummary(); ixsummary(); poolsummary(); + pagersummary(); break; case 'd': if(consdebug != nil) diff --git a/port/fault.c b/port/fault.c index b83fbbe2ac4eca390e4ccce8f47fa9531526a480..1ed8c118cd75081e0cc69921575cf75d71f645e0 100644 --- a/port/fault.c +++ b/port/fault.c @@ -95,13 +95,9 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) lkp = *pg; lock(lkp); - /* uncache the current swap image (since we may be changing it) */ - if(lkp->image){ - if(lkp->image == &swapimage) - uncachepage(lkp); - else - duppage(lkp); - } + /* save a copy of the original for the image cache */ + if(lkp->image) + duppage(lkp); unlock(lkp); goto done; @@ -153,16 +149,9 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) putpage(lkp); } else { - /* uncache the current page (since we may be changing it) - * and, if a text page, put a duplicate back onto - * the free list - */ - if(lkp->image){ - if(lkp->image == &swapimage) - uncachepage(lkp); - else - duppage(lkp); - } + /* save a copy of the original for the image cache */ + if(lkp->image) + duppage(lkp); unlock(lkp); } @@ -200,7 +189,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) void pio(Segment *s, ulong addr, ulong soff, Page **p) { - Page *new, *new2; + Page *new; KMap *k; Chan *c; int n, ask; @@ -208,22 +197,26 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) ulong daddr; Page *loadrec; +retry: loadrec = *p; if(loadrec == 0) { /* from a text/data image */ daddr = s->fstart+soff; new = lookpage(s->image, daddr); + if(new != nil) { + *p = new; + return; + } } else { /* from a swap image */ daddr = swapaddr(loadrec); new = lookpage(&swapimage, daddr); - if(new != nil) + if(new != nil) { putswap(loadrec); + *p = new; + return; + } } - if(new != nil) { /* Page found from cache */ - *p = new; - return; - } qunlock(&s->lk); @@ -254,7 +247,11 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) poperror(); kunmap(k); qlock(&s->lk); - /* race, we may have multiple simultaneous reads */ + + /* + * race, another proc may have gotten here first while + * s->lk was unlocked + */ if(*p == 0) { new->daddr = daddr; cachepage(new, s->image); @@ -265,35 +262,9 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) } else { /* This is paged out */ c = swapimage.c; - qlock(&swapimage.rdlock); /* mutex */ - - /* - * multiple processes could be swapping in the - * same page for the same segment - */ - if(!pagedout(*p)){ - putpage(new); - qunlock(&swapimage.rdlock); - goto done; - } - - /* - * multiple processes could be swapping in the - * same page for different segments - */ - new2 = lookpage(&swapimage, daddr); - if(new2 != nil){ - putpage(new); - *p = new2; - putswap(loadrec); - qunlock(&swapimage.rdlock); - goto done; - } - if(waserror()) { kunmap(k); putpage(new); - qunlock(&swapimage.rdlock); qlock(&s->lk); qunlock(&s->lk); faulterror("sys: page in I/O error"); @@ -307,12 +278,28 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) kunmap(k); qlock(&s->lk); + /* + * race, another proc may have gotten here first + * (and the pager may have run on that page) while + * s->lk was unlocked + */ + if(*p != loadrec){ + if(!pagedout(*p)){ + /* another process did it for me */ + putpage(new); + goto done; + } else { +print("!"); + /* another process and the pager got in */ + putpage(new); + goto retry; + } + } + new->daddr = daddr; cachepage(new, &swapimage); *p = new; putswap(loadrec); - - qunlock(&swapimage.rdlock); } done: diff --git a/port/portdat.h b/port/portdat.h index a610d2db883a317e2cd623313c5fa152a91c1e12..76888f98ea565616b63106dee301e9e29cba42e0 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -326,7 +326,6 @@ struct Image Image *hash; /* Qid hash chains */ Image *next; /* Free list */ int notext; /* no file associated */ - QLock rdlock; /* mutex for reading from image */ }; struct Pte @@ -622,6 +621,7 @@ struct Proc int preempted; /* true if this process hasn't finished the interrupt * that last preempted it */ + ulong qpc; /* pc calling last blocking qlock */ void *ureg; /* User registers for notes */ void *dbgreg; /* User registers for devproc */ diff --git a/port/portfns.h b/port/portfns.h index b5d9373cb7f0a3987acee5171b0522ae2100f34d..8de2eeb0bf5560b13530e7881425f03debf1ff55 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -174,6 +174,7 @@ Block* packblock(Block*); Block* padblock(Block*, int); void pagechainhead(Page*); void pageinit(void); +void pagersummary(void); void panic(char*, ...); int parseether(uchar*, char*); int parsefields(char*, char**, int, char*); diff --git a/port/proc.c b/port/proc.c index 98399b6a66a0a480cf569f60f885e40ab98d4de8..0cae3894ac1cd3b1617d2f99c6b6763df2190e04 100644 --- a/port/proc.c +++ b/port/proc.c @@ -903,9 +903,9 @@ dumpaproc(Proc *p) s = p->psstate; if(s == 0) s = "kproc"; - print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux pri %lud\n", + print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux\n", p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state], - p->time[0], p->time[1], bss, p->priority); + p->time[0], p->time[1], bss, p->qpc); } void diff --git a/port/qlock.c b/port/qlock.c index 89503f8292df5f419114932f4afd47d7ef5622c5..0a06b46c9826bf72566d17094d163eb8999cb7f2 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -35,6 +35,7 @@ rwstats.qlockq++; q->tail = mp; mp->qnext = 0; mp->state = Queueing; + up->qpc = getcallerpc(q); unlock(&q->use); sched(); } diff --git a/port/swap.c b/port/swap.c index acf0c2611c86696c182f63337a50afb7474a64bb..4b7c7504fd698c3be5b55b65243166f06a7b1bbe 100644 --- a/port/swap.c +++ b/port/swap.c @@ -124,7 +124,9 @@ loop: if(p->state == Dead || p->kp) continue; - qlock(&p->seglock); + if(!canqlock(&p->seglock)) + continue; /* process changing its segments */ + for(i = 0; i < NSEG; i++) { if(!needpages(junk)){ qunlock(&p->seglock); @@ -278,19 +280,6 @@ pagepte(int type, Page **pg) case SG_SHARED: case SG_SHDATA: case SG_MAP: - /* if it's already on disk, no need to do io again */ -#ifdef asdf - lock(outp); - if(outp->image == &swapimage){ - dupswap((Page*)outp->daddr); - *pg = (Page*)(outp->daddr|PG_ONSWAP); - unlock(outp); - putpage(outp); - return; - } - unlock(outp); -#endif asdf - /* * get a new swap address and clear any pages * referring to it from the cache @@ -312,6 +301,7 @@ pagepte(int type, Page **pg) /* * enter it into the cache so that a fault happening * during the write will grab the page from the cache + * rather than one partially written to the disk */ outp->daddr = daddr; cachepage(outp, &swapimage); @@ -324,6 +314,15 @@ pagepte(int type, Page **pg) } } +void +pagersummary(void) +{ + print("%lud/%lud memory %lud/%lud swap %d iolist\n", + palloc.user-palloc.freecount, + palloc.user, conf.nswap-swapalloc.free, conf.nswap, + ioptr); +} + static void executeio(void) { @@ -336,13 +335,17 @@ executeio(void) c = swapimage.c; for(i = 0; i < ioptr; i++) { + if(ioptr > conf.nswppo) + panic("executeio: ioptr %d > %d\n", ioptr, conf.nswppo); out = iolist[i]; + up->psstate = "I/Okm"; k = kmap(out); kaddr = (char*)VA(k); if(waserror()) panic("executeio: page out I/O error"); + up->psstate = "I/Owr"; n = devtab[c->type]->write(c, kaddr, BY2PG, out->daddr); if(n != BY2PG) nexterror(); @@ -351,9 +354,11 @@ executeio(void) poperror(); /* Free up the page after I/O */ + up->psstate = "I/Odec"; lock(out); out->ref--; unlock(out); + up->psstate = "I/Oput"; putpage(out); } ioptr = 0;