From e55fcb9d82497bf80d4ec37ec8d3d78d05d070b8 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 11 May 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-05-11 --- gnot/devmnt.c | 94 ++++++++++++++++++++++++++++++++++++--------------- gnot/trap.c | 26 +++++++++----- port/devdk.c | 9 +++-- port/devmnt.c | 94 ++++++++++++++++++++++++++++++++++++--------------- port/stream.c | 7 ++-- port/sturp.c | 64 ++++++++++++++++++++++------------- power/trap.c | 26 +++++++++----- 7 files changed, 218 insertions(+), 102 deletions(-) diff --git a/gnot/devmnt.c b/gnot/devmnt.c index c12610398e67cd682e35c8f6d2ad04e56ba22e59..e2f255d751729a80adf45e58e1f95f67ec2985d4 100644 --- a/gnot/devmnt.c +++ b/gnot/devmnt.c @@ -555,7 +555,6 @@ mntxmit(Mnt *m, Mnthdr *mh) ulong n; Mntbuf *mbr, *mbw; Chan *mntpt, *msg; - int isbit; mbr = mballoc(); mbw = mballoc(); @@ -565,35 +564,21 @@ mntxmit(Mnt *m, Mnthdr *mh) nexterror(); } n = convS2M(&mh->thdr, mbw->buf); - isbit = 0; - if(devchar[m->msg->type] == '3') - isbit = 1; /* - * Avoid qlock for bit, to maximize parallelism + * Bit3 does its own multiplexing. (Well, the file server does.) + * The code is different enough that it's broken out separately here. */ - if(isbit){ - lock(&m->use); /* spin rather than sleep */ - if((msg = m->msg) == 0){ - unlock(&m->use); - error(0, Eshutdown); - } - incref(msg); + if(devchar[m->msg->type] != '3') + goto Normal; + lock(&m->use); /* spin rather than sleep */ + if((msg = m->msg) == 0){ unlock(&m->use); - }else{ - qlock(m); - if((msg = m->msg) == 0){ - qunlock(m); - error(0, Eshutdown); - } - qlock(msg); + error(0, Eshutdown); } + incref(msg); + unlock(&m->use); if(waserror()){ - if(isbit) - close(msg); - else{ - qunlock(m); - qunlock(msg); - } + close(msg); nexterror(); } if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ @@ -605,12 +590,65 @@ mntxmit(Mnt *m, Mnthdr *mh) * Read response */ n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); - if(isbit) - close(msg); - else{ + close(msg); + poperror(); + + if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ + pprint("format error in mntxmit\n"); + error(0, Egreg); + } + + /* + * Various checks + */ + if(mh->rhdr.type != mh->thdr.type+1){ + pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); + error(0, Egreg); + } + if(mh->rhdr.fid != mh->thdr.fid){ + pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); + error(0, Egreg); + } + if(mh->rhdr.err){ + mntpt = m->mntpt; /* unsafe, but Errors are unsafe anyway */ + if(mntpt) + error(mntpt, mh->rhdr.err); + error(0, Eshutdown); + } + + /* + * Copy out on read + */ + if(mh->thdr.type == Tread) + memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); + mbfree(mbr); + mbfree(mbw); + poperror(); + return; + + Normal: + qlock(m); + if((msg = m->msg) == 0){ + qunlock(m); + error(0, Eshutdown); + } + qlock(msg); + if(waserror()){ qunlock(m); qunlock(msg); + nexterror(); } + if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ + pprint("short write in mntxmit\n"); + error(0, Egreg); + } + + /* + * Read response + */ + n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); + qunlock(m); + qunlock(msg); poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ diff --git a/gnot/trap.c b/gnot/trap.c index 2b1777404ee94aeee514547787e83233e45dbe06..eb50678bcfbe94eb5234abe480dc28eef2657767 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -259,18 +259,26 @@ syscall(Ureg *aur) #endif r0 = ur->r0; sp = ur->usp; - if(r0 >= sizeof systab/BY2WD) - panic("syscall %d\n", r0); - if(sp & (BY2WD-1)) - panic("syscall odd sp"); - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD)) - validaddr(sp, 4*BY2WD, 0); u->nerrlab = 0; ret = -1; - if(!waserror()) - ret = (*systab[r0])((ulong*)(sp+BY2WD)); -/* else print("syscall %d err %d %d\n", r0, u->error.type, u->error.code); /**/ + if(!waserror()){ + if(r1 >= sizeof systab/BY2WD){ + pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc); + msg = "bad sys call"; + Bad: + postnote(u->p, 1, msg, NDebug); + error(0, Ebadarg); + } + if(sp & (BY2WD-1)){ + pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); + msg = "odd stack"; + goto Bad; + } + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD)) + validaddr(ur->sp, 4*BY2WD, 0); + ret = (*systab[r1])((ulong*)(sp+2*BY2WD)); + } u->nerrlab = 0; u->p->insyscall = 0; if(r0 == NOTED) /* ugly hack */ diff --git a/port/devdk.c b/port/devdk.c index ab2405073f74fc54f7104867b8000b38f3f1ff8d..4e3f2a168b8635eae52b85dc0ecc06dd880dcad9 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -329,6 +329,8 @@ dkstopen(Queue *q, Stream *s) q->other->ptr = q->ptr = lp = &dp->line[s->id]; lp->dp = dp; lp->rq = q; + if(lp->state == Lclosed) + lp->state = Lopened; } /* @@ -670,7 +672,6 @@ dkopen(Chan *c, int omode) continue; } c->qid = STREAMQID(lp-dp->line, Sctlqid); - qunlock(lp); break; } } @@ -678,6 +679,7 @@ dkopen(Chan *c, int omode) error(0, Enodev); streamopen(c, &dkinfo); pushq(c->stream, &urpinfo); + qunlock(lp); break; case Dlistenqid: /* @@ -727,7 +729,7 @@ dkclose(Chan *c) { Dk *dp; - /* real closing happens in lancestclose */ + /* real closing happens in dkstclose */ if(c->stream) streamclose(c); @@ -899,7 +901,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine) /* * only dial on virgin lines */ - if(lp->state != Lclosed) + if(lp->state != Lopened) error(0, Ebadarg); DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr); @@ -1202,6 +1204,7 @@ dklisten(Chan *c) DPRINT("dklisten returns %d\n", lineno); return lineno; } + panic("dklisten terminates strangely\n"); } /* diff --git a/port/devmnt.c b/port/devmnt.c index c12610398e67cd682e35c8f6d2ad04e56ba22e59..e2f255d751729a80adf45e58e1f95f67ec2985d4 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -555,7 +555,6 @@ mntxmit(Mnt *m, Mnthdr *mh) ulong n; Mntbuf *mbr, *mbw; Chan *mntpt, *msg; - int isbit; mbr = mballoc(); mbw = mballoc(); @@ -565,35 +564,21 @@ mntxmit(Mnt *m, Mnthdr *mh) nexterror(); } n = convS2M(&mh->thdr, mbw->buf); - isbit = 0; - if(devchar[m->msg->type] == '3') - isbit = 1; /* - * Avoid qlock for bit, to maximize parallelism + * Bit3 does its own multiplexing. (Well, the file server does.) + * The code is different enough that it's broken out separately here. */ - if(isbit){ - lock(&m->use); /* spin rather than sleep */ - if((msg = m->msg) == 0){ - unlock(&m->use); - error(0, Eshutdown); - } - incref(msg); + if(devchar[m->msg->type] != '3') + goto Normal; + lock(&m->use); /* spin rather than sleep */ + if((msg = m->msg) == 0){ unlock(&m->use); - }else{ - qlock(m); - if((msg = m->msg) == 0){ - qunlock(m); - error(0, Eshutdown); - } - qlock(msg); + error(0, Eshutdown); } + incref(msg); + unlock(&m->use); if(waserror()){ - if(isbit) - close(msg); - else{ - qunlock(m); - qunlock(msg); - } + close(msg); nexterror(); } if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ @@ -605,12 +590,65 @@ mntxmit(Mnt *m, Mnthdr *mh) * Read response */ n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); - if(isbit) - close(msg); - else{ + close(msg); + poperror(); + + if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ + pprint("format error in mntxmit\n"); + error(0, Egreg); + } + + /* + * Various checks + */ + if(mh->rhdr.type != mh->thdr.type+1){ + pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); + error(0, Egreg); + } + if(mh->rhdr.fid != mh->thdr.fid){ + pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); + error(0, Egreg); + } + if(mh->rhdr.err){ + mntpt = m->mntpt; /* unsafe, but Errors are unsafe anyway */ + if(mntpt) + error(mntpt, mh->rhdr.err); + error(0, Eshutdown); + } + + /* + * Copy out on read + */ + if(mh->thdr.type == Tread) + memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); + mbfree(mbr); + mbfree(mbw); + poperror(); + return; + + Normal: + qlock(m); + if((msg = m->msg) == 0){ + qunlock(m); + error(0, Eshutdown); + } + qlock(msg); + if(waserror()){ qunlock(m); qunlock(msg); + nexterror(); } + if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ + pprint("short write in mntxmit\n"); + error(0, Egreg); + } + + /* + * Read response + */ + n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); + qunlock(m); + qunlock(msg); poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ diff --git a/port/stream.c b/port/stream.c index a0068b560d2a53449a7916c13960eaf6632691a8..72844a3f170413f4d6968add745d53c221c551e9 100644 --- a/port/stream.c +++ b/port/stream.c @@ -78,13 +78,14 @@ dumpqueues(void) continue; for(count = 0, bp = q->first; bp; bp = bp->next) count++; - print("%s %ux RD count %d len %d", q->info->name, q, count, q->len); + print("%s %ux R c %d l %d f %ux", q->info->name, q, count, + q->len, q->flag); for(count = 0, bp = WR(q)->first; bp; bp = bp->next) count++; - print(" WR count %d len %d\n", count, WR(q)->len); + print(" W c %d l %d f %ux\n", count, WR(q)->len, WR(q)->flag); } print("\n"); - for(bcp=bclass; bcp<&bclass[Nclass-1]; bcp++){ + for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){ lock(bcp); for(count = 0, bp = bcp->first; bp; count++, bp = bp->next) ; diff --git a/port/sturp.c b/port/sturp.c index 04ad735358670a4dc8deaff05565ffe1d810c3d1..6e110ff45bf59b33754db78207e5e172b42b286e 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -48,7 +48,6 @@ struct Urp { int blocks; /* output */ - QLock xmit; /* output lock, only one process at a time */ Queue *wq; /* output queue */ int maxout; /* maximum outstanding unacked blocks */ @@ -60,6 +59,7 @@ struct Urp { Block *xb[8]; /* the xmit window buffer */ QLock xl[8]; ulong timer; /* timeout for xmit */ + int rexmit; int kstarted; }; @@ -168,14 +168,6 @@ isflushed(void *a) up = (Urp *)a; return (up->state&HUNGUP) || (up->unechoed==up->nxb && up->wq->len==0); } -static int -isdead(void *a) -{ - Urp *up; - - up = (Urp *)a; - return up->kstarted == 0; -} static void urpclose(Queue *q) { @@ -219,8 +211,10 @@ urpclose(Queue *q) } qunlock(&up->xmit); - if(up->kstarted == 0) + if(up->kstarted == 0){ + DPRINT("urpclose %ux\n", up); up->state = 0; + } } /* @@ -471,6 +465,10 @@ urpiput(Queue *q, Block *bp) urpstat.rjseq++; sendrej(up); break; + } else if(q->next->len > (3*Streamhi)/2 + || q->next->nb > (3*Streambhi)/2) { + flushinput(up); + break; } /* @@ -559,6 +557,7 @@ output(Urp *up) ulong now; Queue *q; int n; + int i; if(!canqlock(&up->xmit)) return; @@ -607,8 +606,7 @@ output(Urp *up) /* * if a retransmit time has elapsed since a transmit, send an ENQ */ - if(up->unechoed != up->next && NOW > up->timer){ - DPRINT("sENQ\n"); + if(up->unechoed!=up->next && NOW>up->timer){ up->timer = NOW + MSrexmit; up->state &= ~REJECTING; sendctl(up, ENQ); @@ -620,11 +618,21 @@ output(Urp *up) /* * if there's a window open, push some blocks out */ - while(WINDOW(up)>0 && up->xb[up->next]!=0 && canqlock(&up->xl[up->next])){ - if(up->xb[up->next]) - sendblock(up, up->next); - qunlock(&up->xl[up->next]); + if(up->rexmit){ + up->rexmit = 0; + up->next = up->unechoed; + } + while(WINDOW(up)>0 && up->xb[up->next]!=0){ + i = up->next; + qlock(&up->xl[i]); + if(waserror()){ + qunlock(&up->xl[i]); + nexterror(); + } + sendblock(up, i); + qunlock(&up->xl[i]); up->next = NEXT(up->next); + poperror(); } qunlock(&up->xmit); poperror(); @@ -745,6 +753,7 @@ rcvack(Urp *up, int msg) { int seqno; int next; + int i; seqno = msg&Nmask; next = NEXT(seqno); @@ -754,11 +763,12 @@ rcvack(Urp *up, int msg) */ if(IN(seqno, up->unacked, up->next)){ for(; up->unacked != next; up->unacked = NEXT(up->unacked)){ - qlock(&up->xl[up->unacked]); - if(up->xb[up->unacked]) - freeb(up->xb[up->unacked]); - up->xb[up->unacked] = 0; - qunlock(&up->xl[up->unacked]); + i = up->unacked; + qlock(&up->xl[i]); + if(up->xb[i]) + freeb(up->xb[i]); + up->xb[i] = 0; + qunlock(&up->xl[i]); } } @@ -786,7 +796,7 @@ rcvack(Urp *up, int msg) */ if(up->unechoed==next && !(up->state & REJECTING)){ up->state |= REJECTING; - up->next = next; + up->rexmit = 1; } break; } @@ -831,6 +841,7 @@ initoutput(Urp *up, int window) up->unacked = 1; up->next = 1; up->nxb = 1; + up->rexmit = 0; /* * free any outstanding blocks @@ -886,6 +897,7 @@ urpkproc(void *arg) up = (Urp *)arg; if(waserror()){ + print("urpkproc error %ux\n", up); up->state = 0; up->kstarted = 0; wakeup(&up->r); @@ -898,10 +910,16 @@ urpkproc(void *arg) if(up->state & HUNGUP) break; } - sendack(up); + if(up->state == 0){ + DPRINT("urpkproc: %ux->state == 0\n", up); + break; + } + if(!QFULL(up->rq->next)) + sendack(up); output(up); tsleep(&up->rq->r, todo, up, MSrexmit/2); } up->state = 0; up->kstarted = 0; + DPRINT("urpkproc %ux\n", up); } diff --git a/power/trap.c b/power/trap.c index 3d3c94208414dd80237a94531e792e1eba4dec5e..3a93435c57798f59ce4f0d77db8ef9c0df447185 100644 --- a/power/trap.c +++ b/power/trap.c @@ -5,6 +5,7 @@ #include "fns.h" #include "ureg.h" #include "io.h" +#include "errno.h" /* * vme interrupt routines @@ -418,6 +419,7 @@ syscall(Ureg *aur) ulong sp; ulong r1; Ureg *ur; + char *msg; u->p->insyscall = 1; ur = aur; @@ -433,17 +435,25 @@ syscall(Ureg *aur) spllo(); r1 = ur->r1; sp = ur->sp; - if(r1 >= sizeof systab/BY2WD) - panic("syscall %d\n", r1); - if(sp & (BY2WD-1)) - panic("syscall odd sp"); - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD)) - validaddr(ur->sp, 4*BY2WD, 0); - u->nerrlab = 0; ret = -1; - if(!waserror()) + if(!waserror()){ + if(r1 >= sizeof systab/BY2WD){ + pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc); + msg = "bad sys call"; + Bad: + postnote(u->p, 1, msg, NDebug); + error(0, Ebadarg); + } + if(sp & (BY2WD-1)){ + pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); + msg = "odd stack"; + goto Bad; + } + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD)) + validaddr(ur->sp, 4*BY2WD, 0); ret = (*systab[r1])((ulong*)(sp+2*BY2WD)); + } ur->pc += 4; u->nerrlab = 0; splhi();