M gnot/devmnt.c => gnot/devmnt.c +66 -28
@@ 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){
M gnot/trap.c => gnot/trap.c +17 -9
@@ 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 */
M port/devdk.c => port/devdk.c +6 -3
@@ 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");
}
/*
M port/devmnt.c => port/devmnt.c +66 -28
@@ 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){
M port/stream.c => port/stream.c +4 -3
@@ 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)
;
M port/sturp.c => port/sturp.c +41 -23
@@ 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);
}
M power/trap.c => power/trap.c +18 -8
@@ 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();