From bffc34b1d0eade0f7dfd2058c24981284a85193f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 3 Mar 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-03-03 --- port/devmux.c | 94 +++++++-------- port/devwren.c | 1 + port/fault.c | 2 + port/ipdat.h | 3 + port/page.c | 38 ++++--- port/portdat.h | 6 +- port/proc.c | 5 +- port/stil.c | 51 +++++---- port/stnoether.c | 289 ----------------------------------------------- port/streboot.c | 47 ++++++++ port/swap.c | 108 +++++++++--------- port/tcpif.c | 12 ++ 12 files changed, 224 insertions(+), 432 deletions(-) delete mode 100644 port/stnoether.c create mode 100644 port/streboot.c diff --git a/port/devmux.c b/port/devmux.c index 45cce58faeb8afce7ad8c292733616fa958b7641..832b29744c23c7937b34e46bf1841d89bb4150be 100644 --- a/port/devmux.c +++ b/port/devmux.c @@ -291,6 +291,53 @@ muxcreate(Chan *c, char *name, int omode, ulong perm) c->mode = omode; } +void +muxclose(Chan *c) +{ + Block *f1, *f2; + Con *cm, *e; + Mux *m; + int nc; + + if(c->qid.path&CHDIR) + return; + + m = &muxes[NMUX(c)]; + if(!(c->flag&COPEN) || m->srv) + return; + + nc = NCON(c); + f1 = 0; + f2 = 0; + switch(nc) { + case Qhead: + m->headopen = 0; + cm = m->connects; + for(e = &cm[Nmux]; cm < e; cm++) + if(cm->ref) + wakeup(&cm->conq.r); + lock(m); + if(--m->ref == 0) + f1 = muxclq(&m->headq); + unlock(m); + break; + case Qclone: + break; + default: + lock(m); + cm = &m->connects[nc-Qoffset]; + if(--cm->ref == 0) + f1 = muxclq(&cm->conq); + if(--m->ref == 0) + f1 = muxclq(&m->headq); + unlock(m); + } + if(f1) + freeb(f1); + if(f2) + freeb(f2); +} + void muxremove(Chan *c) { @@ -355,53 +402,6 @@ muxwstat(Chan *c, char *db) } } -void -muxclose(Chan *c) -{ - Block *f1, *f2; - Con *cm, *e; - Mux *m; - int nc; - - if(c->qid.path&CHDIR) - return; - - m = &muxes[NMUX(c)]; - if(!(c->flag&COPEN) || m->srv) - return; - - nc = NCON(c); - f1 = 0; - f2 = 0; - switch(nc) { - case Qhead: - m->headopen = 0; - cm = m->connects; - for(e = &cm[Nmux]; cm < e; cm++) - if(cm->ref) - wakeup(&cm->conq.r); - lock(m); - if(--m->ref == 0) - f1 = muxclq(&m->headq); - unlock(m); - break; - case Qclone: - break; - default: - lock(m); - cm = &m->connects[nc-Qoffset]; - if(--cm->ref == 0) - f1 = muxclq(&cm->conq); - if(--m->ref == 0) - f1 = muxclq(&m->headq); - unlock(m); - } - if(f1) - freeb(f1); - if(f2) - freeb(f2); -} - long muxread(Chan *c, void *va, long n, ulong offset) { diff --git a/port/devwren.c b/port/devwren.c index 6b79728aac820a5e90897ad2f13ce5cc771fb213..2f3f4ccd397093daf7b1ed9e18ae1522014fbf3c 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -326,5 +326,6 @@ wrenpart(int dev) dp->npart = pp - dp->p; poperror(); scsifree(b); + poperror(); qunlock(dp); } diff --git a/port/fault.c b/port/fault.c index 32399d2a04001a55b9b95dadc75c262d201dcdb7..e703a01fd82e25e81968b109820085b73bf1186b 100644 --- a/port/fault.c +++ b/port/fault.c @@ -170,6 +170,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) new = lookpage(s->image, daddr); } else { +print("reclaim\n"); daddr = swapaddr(loadrec); new = lookpage(&swapimage, daddr); if(new) @@ -221,6 +222,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) putpage(new); } else { /* This is paged out */ +print("SWAPIN\n"); c = swapimage.c; qlock(&c->rdl); diff --git a/port/ipdat.h b/port/ipdat.h index e19f672e62f8bdec0098d06ec460b309e05444f6..f296106100b825f28ff0d3271f58bd661f34af7e 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -98,6 +98,8 @@ struct Ilcb /* Control block */ { int state; /* Connection state */ + Rendez syncer; /* where syncer waits for a connect */ + QLock ackq; /* Unacknowledged queue */ Block *unacked; Block *unackedtail; @@ -247,6 +249,7 @@ struct Tcpctl { QLock; struct Tctl; + Rendez syner; }; struct Tcp diff --git a/port/page.c b/port/page.c index dd5770768a6dd7f3efe8bd17e3aae85b68b505c4..33a65191386bc66b3cc4677e44894d38f9338fe4 100644 --- a/port/page.c +++ b/port/page.c @@ -103,7 +103,7 @@ void pageinit(void) { ulong np, addr, lim; - ulong i, vmem, pmem; + ulong i, vmem, pmem, hw, hr; Page *p; /* @@ -150,7 +150,15 @@ pageinit(void) palloc.user = palloc.freecount = p - palloc.head; pmem = palloc.user*BY2PG/1024; vmem = pmem + ((conf.nswap)*BY2PG)/1024; - print("%lud free pages, %dK bytes, swap %dK bytes\n", palloc.user, pmem, vmem); + + /* Pageing numbers */ + swapalloc.highwater = (palloc.freecount*5)/100; + swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4); + hw = (swapalloc.highwater*BY2PG)/1024; + hr = (swapalloc.headroom*BY2PG)/1024; + + print("%lud free pages, %dK bytes, swap %dK bytes, highwater %dK, headroom %dK\n", + palloc.user, pmem, vmem, hw, hr); } Page* @@ -166,7 +174,7 @@ newpage(int clear, Segment **s, ulong va) lock(&palloc); /* The kp test is a poor guard against the pager deadlocking */ - while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) { + while((palloc.freecount < swapalloc.highwater && u->p->kp == 0)||palloc.freecount == 0) { palloc.wanted++; unlock(&palloc); if(s && *s) { @@ -223,53 +231,54 @@ int ispages(void *p) { USED(p); - return palloc.freecount >= HIGHWATER; + return palloc.freecount >= swapalloc.highwater; } void putpage(Page *p) { - int count; + int wake; if(onswap(p)) { putswap(p); return; } + wake = 0; lockpage(p); if(--p->ref == 0) { lock(&palloc); - if(p->image) { + if(p->image && p->image != &swapimage) { if(palloc.tail) { p->prev = palloc.tail; palloc.tail->next = p; - palloc.tail = p; } else { - palloc.head = palloc.tail = p; + palloc.head = p; p->prev = 0; } + palloc.tail = p; p->next = 0; } else { if(palloc.head) { p->next = palloc.head; palloc.head->prev = p; - palloc.head = p; } else { - palloc.head = palloc.tail = p; + palloc.tail = p; p->next = 0; } + palloc.head = p; p->prev = 0; } + wake = 1; palloc.freecount++; /* Release people waiting for memory */ unlock(&palloc); } unlockpage(p); - - if(palloc.wanted) + if(wake && palloc.wanted) wakeup(&palloc.r); } @@ -297,8 +306,9 @@ duppage(Page *p) /* Always call with p locked */ lock(&palloc); - if(palloc.freecount < HIGHWATER || /* No freelist cache when memory is very low */ - p->image == &swapimage) { /* No dup for swap pages */ + /* No freelist cache when memory is very low, No dup for swap pages */ + if(palloc.freecount < swapalloc.highwater || + p->image == &swapimage) { unlock(&palloc); uncachepage(p); return; diff --git a/port/portdat.h b/port/portdat.h index 0e4d84eff625ee98d066e769985c7279ef1f51cb..bcf63e2902ceaed03579eec342393880b0328fee 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -311,6 +311,8 @@ struct Swapalloc char *alloc; /* Round robin allocator */ char *top; /* Top of swap map */ Rendez r; /* Pager kproc idle sleep */ + ulong highwater; /* Threshold beyond which we must page */ + ulong headroom; /* Space pager attempts to clear below highwater */ }swapalloc; struct Image @@ -343,10 +345,8 @@ struct Pte #define SG_SHARED 004 #define SG_PHYSICAL 005 /* Segment flags */ -#define SG_RONLY 040 /* Segment is read only */ +#define SG_RONLY 040 /* Segment is read only */ -#define HIGHWATER ((conf.npage*5)/100) -#define MAXHEADROOM HIGHWATER*2 /* Silly but OK for debug */ #define PG_ONSWAP 1 #define pagedout(s) (((ulong)s)==0 || (((ulong)s)&PG_ONSWAP)) #define swapaddr(s) (((ulong)s)&~PG_ONSWAP) diff --git a/port/proc.c b/port/proc.c index 19cfd83bcbfa47e1ab21c449f1e8308315f6e7f5..8767ae2188cde141ff4c0589dc578c169e3e41d6 100644 --- a/port/proc.c +++ b/port/proc.c @@ -522,7 +522,10 @@ pexit(char *exitstr, int freemem) * if not a kernel process and have a parent, * do some housekeeping. */ - if(c->kp == 0 && (p = c->parent)) { + if(c->kp == 0) { + if((p = c->parent) == 0) + panic("boot process died"); + wq = newwaitq(); wq->w.pid = c->pid; utime = c->time[TUser] + c->time[TCUser]; diff --git a/port/stil.c b/port/stil.c index f71bc3247b29637e8fe8e32cf3e895ae2968e408..bce701d3bead6400fad9df6bff21d51629bfff1a 100644 --- a/port/stil.c +++ b/port/stil.c @@ -257,8 +257,8 @@ ilrcvmsg(Ipconv *ipc, Block *bp) dst = nhgetl(ih->src); if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) { - st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype]; -/* print("il: cksum error, pkt(%s id %lud ack %lud %d.%d.%d.%d/%d->%d)\n", +/* st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype]; + print("il: cksum error, pkt(%s id %lud ack %lud %d.%d.%d.%d/%d->%d)\n", st, nhgetl(ih->ilid), nhgetl(ih->ilack), fmtaddr(dst), sp, dp); /**/ goto drop; } @@ -343,24 +343,21 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp) default: break; case Ilsync: - if(ack != ic->start) { - ic->state = Ilclosed; + if(ack != ic->start) ilhangup(s, "connection rejected"); - } else { ic->recvd = id; ic->rstart = id; ilsendctl(s, 0, Ilack, ic->next, ic->recvd); ic->state = Ilestablished; + wakeup(&ic->syncer); ilpullup(s); Starttimer(ic); } break; case Ilclose: - if(ack == ic->start) { - ic->state = Ilclosed; + if(ack == ic->start) ilhangup(s, "remote close"); - } break; } freeb(bp); @@ -386,10 +383,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp) } break; case Ilclose: - if(id == ic->next) { - ic->state = Ilclosed; + if(id == ic->next) ilhangup(s, "remote close"); - } break; } freeb(bp); @@ -397,10 +392,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp) case Ilestablished: switch(h->iltype) { case Ilsync: - if(id != ic->start) { - ic->state = Ilclosed; + if(id != ic->start) ilhangup(s, "remote close"); - } else { ilsendctl(s, 0, Ilack, ic->next, ic->rstart); Starttimer(ic); @@ -458,10 +451,8 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp) case Ilclose: ic->recvd = id; ilsendctl(s, 0, Ilclose, ic->next, ic->recvd); - if(ack == ic->next) { - ic->state = Ilclosed; + if(ack == ic->next) ilhangup(s, 0); - } Starttimer(ic); break; default: @@ -522,8 +513,14 @@ ilhangup(Ipconv *s, char *msg) { Block *nb; int l; + Ilcb *ic; + int callout; DBG("hangup! %s %d/%d\n", msg ? msg : "??", s->psrc, s->pdst); + + ic = &s->ilctl; + callout = ic->state == Ilsyncer; + ic->state = Ilclosed; if(s->readq) { if(msg) { l = strlen(msg); @@ -537,6 +534,8 @@ ilhangup(Ipconv *s, char *msg) nb->flags |= S_DELIM; PUTNEXT(s->readq, nb); } + if(callout) + wakeup(&ic->syncer); s->psrc = 0; s->pdst = 0; s->dst = 0; @@ -697,10 +696,8 @@ ilackproc(void *a) ilsendctl(s, 0, Ilclose, ic->next, ic->recvd); ilbackoff(ic); } - if(ic->timeout >= ic->slowtime) { - ic->state = Ilclosed; + if(ic->timeout >= ic->slowtime) ilhangup(s, 0); - } break; case Ilsyncee: case Ilsyncer: @@ -708,10 +705,8 @@ ilackproc(void *a) ilsendctl(s, 0, Ilsync, ic->start, ic->recvd); ilbackoff(ic); } - if(ic->timeout >= ic->slowtime) { - ic->state = Ilclosed; + if(ic->timeout >= ic->slowtime) ilhangup(s, etime); - } break; case Ilestablished: ic->acktime -= Iltickms; @@ -721,7 +716,6 @@ ilackproc(void *a) if(ic->querytime <= 0){ ic->deathtime -= Querytime; if(ic->deathtime < 0){ - ic->state = Ilclosed; ilhangup(s, etime); break; } @@ -737,7 +731,6 @@ ilackproc(void *a) ilbackoff(ic); } if(ic->timeout >= ic->slowtime) { - ic->state = Ilclosed; ilhangup(s, etime); break; } @@ -756,6 +749,11 @@ ilbackoff(Ilcb *ic) ic->fasttime = (ic->fasttime)*3/2; } +static int +notsyncer(void *ic) +{ + return ((Ilcb*)ic)->state != Ilsyncer; +} void ilstart(Ipconv *ipc, int type, int window) { @@ -783,6 +781,9 @@ ilstart(Ipconv *ipc, int type, int window) case IL_ACTIVE: ic->state = Ilsyncer; ilsendctl(ipc, 0, Ilsync, ic->start, ic->recvd); + sleep(&ic->syncer, notsyncer, ic); + if(ic->state == Ilclosed) + error(Etimedout); break; } } diff --git a/port/stnoether.c b/port/stnoether.c deleted file mode 100644 index 8d5e5db19c240190ef45f359d7bc10b586c4b3a7..0000000000000000000000000000000000000000 --- a/port/stnoether.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * ethernet specific multiplexor for nonet - * - * this line discipline gets pushed onto an ethernet channel - * to demultiplex/multiplex nonet conversations. - */ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/nonet.h" - -#define DPRINT if(pnonet)print -extern int pnonet; - -static void etherparse(uchar*, char*); -static void noetherclose(Queue*); -static void noetheriput(Queue*, Block*); -static void noetheropen(Queue*, Stream*); -static void noetheroput(Queue*, Block*); - -/* - * ethernet header of a packet - */ -#define EHDRSIZE (ETHERHDRSIZE + NO_HDRSIZE) -#define EMAXBODY (ETHERMAXTU - EHDRSIZE) /* maximum ethernet packet body */ -#define ETHER_TYPE 0x900 /* most significant byte last */ - -/* - * the ethernet multiplexor stream module definition - */ -Qinfo noetherinfo = -{ - noetheriput, - noetheroput, - noetheropen, - noetherclose, - "noether" -}; - -/* - * perform the ether specific part of nonetconnect. just stick - * the address into the prototype header. - */ -void -noetherconnect(Noconv *cp, char *ea) -{ - Etherpkt *eh; - - eh = (Etherpkt*)cp->media->rptr; - etherparse(eh->d, ea); - eh->type[0] = ETHER_TYPE>>8; - eh->type[1] = ETHER_TYPE & 0xff; -} - -/* - * set up an ether interface - */ -static void -noetheropen(Queue *q, Stream *s) -{ - streamenter(s); - nonetnewifc(q, s, ETHERMAXTU, ETHERMINTU, ETHERHDRSIZE, noetherconnect); -} - -/* - * tear down an ether interface - */ -static void -noetherclose(Queue *q) -{ - Noifc *ifc; - - ifc = (Noifc*)q->ptr; - nonetfreeifc(ifc); -} - -/* - * configure the system - */ -static void -noetheroput(Queue *q, Block *bp) -{ - Noifc *ifc; - - ifc = (Noifc*)q->ptr; - if(bp->type != M_DATA){ - if(streamparse("config", bp)){ - if(*bp->rptr == 0) - strcpy(ifc->name, "nonet"); - else - strncpy(ifc->name, (char *)bp->rptr, sizeof(ifc->name)); - } else - PUTNEXT(q, bp); - return; - } - - PUTNEXT(q, bp); -} - -/* - * respond to a misaddressed message with a close - */ -void -noetherbad(Noifc *ifc, Block *bp, int circuit) -{ - Etherpkt *eh, *neh; - Nohdr *nh, *nnh; - Block *nbp; - int r; - Noconv *cp, *ep; - - /* - * crack the packet header - */ - eh = (Etherpkt*)bp->rptr; - nh = (Nohdr*)eh->data; -/* print("bad %.2ux%.2ux%.2ux%.2ux%.2ux%.2ux c %d m %d f %d\n", - eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4], - eh->s[5], circuit, nh->mid, nh->flag); /**/ - if(nh->flag & NO_RESET) - goto out; - - /* - * only one reset per message - */ - r = (nh->remain[1]<<8) | nh->remain[0]; - if(r<0) - goto out; - - /* - * craft an error reply - */ -/* print("sending reset\n"); /**/ - nbp = allocb(60); - nbp->flags |= S_DELIM; - nbp->wptr = nbp->rptr + 60; - memset(bp->rptr, 0, 60); - neh = (Etherpkt *)nbp->rptr; - nnh = (Nohdr*)neh->data; - memmove(neh, eh, EHDRSIZE); - nnh->circuit[0] ^= 1; - nnh->remain[0] = nnh->remain[1] = 0; - nnh->flag = NO_HANGUP | NO_RESET; - nnh->ack = nh->mid; - nnh->mid = nh->ack; - memmove(neh->s, eh->d, sizeof(neh->s)); - memmove(neh->d, eh->s, sizeof(neh->d)); - nonetcksum(nbp, ETHERHDRSIZE); - PUTNEXT(ifc->wq, nbp); -out: - freeb(bp); -} - -/* - * Input a packet and use the ether address to select the correct - * nonet device to pass it to. - * - * Simplifying assumption: one put == one packet && the complete header - * is in the first block. If this isn't true, demultiplexing will not work. - */ -static void -noetheriput(Queue *q, Block *bp) -{ - Noifc *ifc; - int circuit; - Noconv *cp, *ep; - Etherpkt *eh, *peh; - Nohdr *nh; - ulong s; - Block *nbp; - int next; - Nocall *clp; - - if(bp->type != M_DATA){ - PUTNEXT(q, bp); - return; - } - - ifc = (Noifc*)q->ptr; - eh = (Etherpkt*)bp->rptr; - nh = (Nohdr*)eh->data; - circuit = (nh->circuit[2]<<16) | (nh->circuit[1]<<8) | nh->circuit[0]; - s = (nh->sum[1]<<8) | nh->sum[0]; - if(s && s!=nonetcksum(bp, ETHERHDRSIZE)){ - print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/ - freeb(bp); - return; - } - - /* - * look for an existing circuit. - */ - ep = &ifc->conv[conf.nnoconv]; - for(cp = &ifc->conv[0]; cp < ep; cp++){ - nbp = cp->media; - if(nbp == 0) - continue; - peh = (Etherpkt*)nbp->rptr; - if(circuit==cp->rcvcircuit && memcmp(peh->d, eh->s, sizeof(eh->s))==0){ - if(!canqlock(cp)){ - freeb(bp); - return; - } - peh = (Etherpkt*)nbp->rptr; - if(circuit==cp->rcvcircuit - && memcmp(peh->d, eh->s, sizeof(eh->s))==0){ - bp->rptr += ifc->hsize; - nonetrcvmsg(cp, bp); - qunlock(cp); - return; - } - qunlock(cp); - } - } - - /* - * if not a new call, then its misaddressed - */ - if((nh->flag & NO_NEWCALL) == 0 || nh->mid != 1){ - noetherbad(ifc, bp, circuit); - return; - } - - /* - * Queue call in a circular queue and wakeup a listener. - */ - lock(&ifc->lock); - next = (ifc->wptr + 1) % Nnocalls; - if(next == ifc->rptr){ - /* no room in the queue */ - unlock(&ifc->lock); - freeb(bp); - return; - } - clp = &ifc->call[ifc->wptr]; - sprint(clp->raddr, "%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux", - eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4], eh->s[5]); - clp->circuit = circuit^1; - bp->rptr += ifc->hsize; - clp->msg = bp; - ifc->wptr = next; - unlock(&ifc->lock); - wakeup(&ifc->listenr); - DPRINT("call from %s wptr %d\n", clp->raddr, ifc->wptr); -} - -/* - * parse an ethernet address (assumed to be 12 ascii hex digits) - */ -static void -etherparse(uchar *to, char *from) -{ - ulong ip; - uchar nip[4]; - int tdig; - int fdig; - int i; - -#ifdef MAGNUM - /* Dot means ip address */ - if(strchr(from, '.')) { - ip = ipparse(from); - if(ip == 0) - error(Enetaddr); - - hnputl(nip, ip); - if(arp_lookup(nip, to)) - return; - } -#endif - - if(strlen(from) != 12) - error(Enetaddr); - - for(i = 0; i < 6; i++){ - fdig = (*from++)&0x7f; - tdig = fdig >= 'a' ? ((fdig - 'a') + 10) - : (fdig >= 'A' ? ((fdig - 'A') + 10) : (fdig - '0')); - fdig = (*from++)&0x7f; - tdig <<= 4; - tdig |= fdig >= 'a' ? ((fdig - 'a') + 10) - : (fdig >= 'A' ? ((fdig - 'A') + 10) : (fdig - '0')); - *to++ = tdig; - } -} diff --git a/port/streboot.c b/port/streboot.c new file mode 100644 index 0000000000000000000000000000000000000000..c2ebc814fc1fd1b992c9a139fdec0b9620343085 --- /dev/null +++ b/port/streboot.c @@ -0,0 +1,47 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +/* + * reboot stream module definition + */ +static void rebootopen(Queue*, Stream*); +static void rebootiput(Queue*, Block*); +static void rebootoput(Queue*, Block*); +static void rebootreset(void); +Qinfo rebootinfo = +{ + rebootiput, + rebootoput, + rebootopen, + 0, + "reboot", + 0 +}; + +static void +rebootopen(Queue *q, Stream *s) +{ + USED(q); + if(strcmp(u->p->user, eve) != 0) + error(Eperm); +} + +void +rebootoput(Queue *q, Block *bp) +{ + PUTNEXT(q, bp); +} + +static void +rebootiput(Queue *q, Block *bp) +{ + if(bp->type == M_HANGUP){ + print("lost connection to fs, rebooting"); + exit(); + } + PUTNEXT(q, bp); +} diff --git a/port/swap.c b/port/swap.c index 7828e1e16823e5af8eafbfbab22a0f94440f00ab..6deb4fc2c4f6c3d7d02b2e967a86be79e2021092 100644 --- a/port/swap.c +++ b/port/swap.c @@ -15,9 +15,11 @@ int canflush(Proc *p, Segment*); enum { - Maxpages = 100, /* Max number of pageouts per segment pass */ + Maxpages = 500, /* Max number of pageouts per segment pass */ }; +#define DBG if(1)print + Image swapimage; static int swopen; Page *iolist[Maxpages]; @@ -103,43 +105,49 @@ pager(void *junk) Segment *s; int i; + if(waserror()) + panic("pager: os error\n"); + USED(junk); p = proctab(0); ep = &p[conf.nproc]; - for(;;) { - if(waserror()) - panic("pager: os error\n"); - u->p->psstate = "Idle"; - sleep(&swapalloc.r, needpages, 0); - u->p->psstate = "Pageout"; +loop: + u->p->psstate = "Idle"; + sleep(&swapalloc.r, needpages, 0); + u->p->psstate = "Pageout"; - for(p = proctab(0); p < ep; p++) { - if(p->state == Dead || p->kp) - continue; + for(;;) { + p++; + if(p > ep) + p = proctab(0); - if(swapimage.c) { - for(i = 0; i < NSEG; i++) - if(s = p->seg[i]) { - pageout(p, s); - executeio(); - } - } - else - if(palloc.freecount < HIGHWATER) { - /* Rob made me do it ! */ - if(conf.cntrlp == 0) - freebroken(); - - /* Emulate the old system if no swap channel */ - print("no physical memory\n"); - tsleep(&swapalloc.r, return0, 0, 1000); - wakeup(&palloc.r); + if(p->state == Dead || p->kp) + continue; + + if(swapimage.c) { + for(i = 0; i < NSEG; i++) { + if(!needpages(junk)) + goto loop; + if(s = p->seg[i]) { + pageout(p, s); + executeio(); + } } } - - poperror(); + else + if(palloc.freecount < swapalloc.highwater) { + /* Rob made me do it ! */ + if(conf.cntrlp == 0) + freebroken(); + + /* Emulate the old system if no swap channel */ + print("no physical memory\n"); + tsleep(&swapalloc.r, return0, 0, 1000); + wakeup(&palloc.r); + } } + goto loop; } void @@ -147,13 +155,20 @@ pageout(Proc *p, Segment *s) { Pte **sm, **endsm, *l; Page **pg, *entry; - int type; + int type, nr; extern char *sname[]; + if(!canqlock(&s->lk)) /* We cannot afford to wait, we will surely deadlock */ return; - if(!canflush(p, s) || s->steal) { + if(s->steal) { + qunlock(&s->lk); + putseg(s); + return; + } + + if(!canflush(p, s)) { qunlock(&s->lk); putseg(s); return; @@ -166,6 +181,7 @@ extern char *sname[]; } scavenge = 0; + nr = 0; /* Pass through the pte tables looking for memory pages to swap out */ type = s->type&SG_TYPE; @@ -175,13 +191,13 @@ extern char *sname[]; if(l == 0) continue; for(pg = l->first; pg < l->last; pg++) { + nr++; entry = *pg; if(pagedout(entry)) continue; - if(entry->modref & PG_REF) { - print("MODREF\n"); + + if(entry->modref & PG_REF) entry->modref &= ~PG_REF; - } else pagepte(type, s, pg); @@ -190,8 +206,9 @@ extern char *sname[]; } } out: - - print("%s: %d: type %s %d pages\n", p->text, p->pid, sname[type], scavenge); + DBG("%s: %d: %5s s %d nr %d fr %d\n", + p->text, p->pid, sname[type], scavenge, nr, palloc.freecount); + poperror(); qunlock(&s->lk); putseg(s); @@ -235,14 +252,9 @@ int pagepte(int type, Segment *s, Page **pg) { ulong daddr; - char *kaddr; - int n; - Chan *c; Page *outp; - KMap *k; outp = *pg; -print("outp: %lux\n", *pg); switch(type) { case SG_TEXT: /* Revert to demand load */ putpage(outp); @@ -290,17 +302,7 @@ executeio(void) for(i = 0; i < ioptr; i++) { out = iolist[i]; -#ifdef asdf - if(out->ref > 2) { - lockpage(out); - if(out->ref > 2) { - out->ref -= 2; - unlockpage(out); - continue; - } - unlockpage(out); - } -#endif + k = kmap(out); kaddr = (char*)VA(k); qlock(&c->wrl); @@ -330,7 +332,7 @@ int needpages(void *p) { USED(p); - return palloc.freecount < HIGHWATER+MAXHEADROOM; + return palloc.freecount < swapalloc.headroom; } void diff --git a/port/tcpif.c b/port/tcpif.c index 8b22d7971b2601d3f87897bab0b5a72b415ea577..8e0bc8b0fbcb6e8b8933a2b0f5aa4ced8f903a10 100644 --- a/port/tcpif.c +++ b/port/tcpif.c @@ -15,6 +15,7 @@ state_upcall(Ipconv *s, char oldstate, char newstate) { Block *bp; int len; + Tcpctl *tcb = &s->tcpctl; DPRINT("state_upcall: %s -> %s err %s\n", tcpstate[oldstate], tcpstate[newstate], s->err); @@ -48,8 +49,16 @@ state_upcall(Ipconv *s, char oldstate, char newstate) qunlock(s); break; } + + if(oldstate == Syn_sent) + wakeup(&tcb->syner); } +static int +notsyner(void *ic) +{ + return ((Tcpctl*)ic)->state != Syn_sent; +} void tcpstart(Ipconv *s, int mode, ushort window, char tos) { @@ -76,6 +85,9 @@ tcpstart(Ipconv *s, int mode, ushort window, char tos) setstate(s, Syn_sent); tcp_output(s); qunlock(tcb); + sleep(&tcb->syner, notsyner, tcb); + if(tcb->state != Established && tcb->state != Syn_received) + error(Etimedout); break; } }