From 38e1a3ef0538f0308a8830de9cec92f0aa029fde Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 25 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-25 --- boot/aux.c | 4 +- gnot/dat.h | 14 +- gnot/devduart.c | 4 +- gnot/main.c | 14 +- gnot/mmu.c | 22 +-- gnot/trap.c | 25 +-- pc/dat.h | 29 +--- pc/devether.c | 17 +- pc/devfloppy.c | 4 +- pc/devhard.c | 6 +- pc/devincon.c | 2 +- pc/devuart.c | 4 +- pc/fns.h | 2 + pc/main.c | 49 ++---- pc/mem.h | 1 + pc/mmu.c | 8 +- pc/trap.c | 6 +- port/alloc.c | 30 +++- port/devboot.c | 14 +- port/devdk.c | 216 +++++++++++-------------- port/devenv.c | 42 ++++- port/devip.c | 23 +-- port/devpipe.c | 6 +- port/devscsi.c | 49 +----- port/fault.c | 6 +- port/ipdat.h | 407 +++++++++++++++++++++++------------------------- port/net.c | 7 +- port/page.c | 93 ++++------- port/pgrp.c | 40 ----- port/portdat.h | 131 ++++++++-------- port/portfns.h | 4 +- port/segment.c | 22 ++- port/stream.c | 79 +++++----- port/swap.c | 8 +- power/dat.h | 2 +- power/main.c | 7 +- power/trap.c | 26 ++-- ss/dat.h | 4 +- ss/main.c | 1 - ss/trap.c | 18 ++- 40 files changed, 642 insertions(+), 804 deletions(-) diff --git a/boot/aux.c b/boot/aux.c index c87a0ced74c2ec8002bf8638cd1ed45c16efc10b..232be78985620355af0b388eba2e57520041d961 100644 --- a/boot/aux.c +++ b/boot/aux.c @@ -148,7 +148,7 @@ outin(char *prompt, char *def, int len) /* * get second word of the terminal environment variable. If it - * ends in "boot", get work of that part. + * ends in "boot", get rid of that part. */ void getconffile(char *conffile, char *terminal) @@ -169,7 +169,7 @@ getconffile(char *conffile, char *terminal) *conffile++ = *p++; *conffile = 0; - /* dump a trailig boot */ + /* dump a trailing boot */ n = strlen(s); if(n > 4 && strcmp(s + n - 4, "boot") == 0) *(s+n-4) = 0; diff --git a/gnot/dat.h b/gnot/dat.h index 479142464098640dbe310e2ef5746b9159c0095f..2b961ea633d329f3bfe17191efbbc22c132c90e4 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -76,22 +76,12 @@ struct Conf ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ ulong nswap; /* number of swap blocks */ - int nenv; /* distinct environment values */ - int nenvchar; /* environment text storage */ - int npgenv; /* environment files per process group */ - int nmux; /* number of mux devices */ - int nstream; /* streams */ - int nqueue; /* stream queues */ - int nsrv; /* public servers (devsrv.c) */ - int nurp; /* max urp conversations */ - int nasync; /* number of async protocol modules */ int nfsyschan; /* number of filsys open channels */ int nisdn; /* number of isdn interfaces */ int nlapd; /* number of dragnet protocol modules */ int copymode; /* 0 is copy on write, 1 is copy on reference */ int portispaged; /* ??? */ int cntrlp; /* panic on ^P */ - int dkif; /* number of datakit interfaces */ int nconc; /* number of datakit concentrators */ }; @@ -147,15 +137,12 @@ struct Portpage int select; }; -extern Portpage portpage; extern int portispaged; -extern int (*portservice[])(void); struct Scsibuf { void *virt; void *phys; - Scsibuf *next; }; #define NERR 25 @@ -171,6 +158,7 @@ struct User char elem[NAMELEN]; /* last name element from namec */ Chan *slash; Chan *dot; + Sargs s; /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/gnot/devduart.c b/gnot/devduart.c index 1820e1a36787c27f0f090fc6a4bbd27d9c0f1f62..696ba8bcd89282644e56deac692e77e5a6271f69 100644 --- a/gnot/devduart.c +++ b/gnot/devduart.c @@ -645,9 +645,9 @@ duartreset(void) if(dp->nostream) return; - dp->iq = ialloc(sizeof(IOQ), 0); + dp->iq = xalloc(sizeof(IOQ)); initq(dp->iq); - dp->oq = ialloc(sizeof(IOQ), 0); + dp->oq = xalloc(sizeof(IOQ)); initq(dp->oq); duartenable(dp); } diff --git a/gnot/main.c b/gnot/main.c index f3d0cdc84891929e83d70433f49002607c601f75..f851ee2fd89c3a77cadcab8e559c828aaf2a1d23 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -40,20 +40,19 @@ main(void) active.machs = 1; mmuinit(); confinit(); + xinit(); kmapinit(); duartinit(); screeninit(); printinit(); print("bank 0: %dM bank 1: %dM\n", bank[0], bank[1]); flushmmu(); + pageinit(); procinit0(); initseg(); - grpinit(); - chaninit(); chandevreset(); streaminit(); swapinit(); - pageinit(); kmapinit(); userinit(); schedinit(); @@ -318,18 +317,9 @@ confinit(void) conf.nproc = 50*mul; conf.nswap = 4096; conf.nimage = 50; - conf.nenv = 100*mul; - conf.nenvchar = 8000*mul; - conf.npgenv = 200*mul; - conf.nstream = 40 + 32*mul; - conf.nqueue = 5 * conf.nstream; - conf.nmux = 10; - conf.nurp = 32; - conf.nasync = 1; conf.copymode = 0; /* copy on write */ conf.portispaged = 0; conf.cntrlp = 0; - conf.dkif = 2; confinit1(mul); } diff --git a/gnot/mmu.c b/gnot/mmu.c index 6081ebe4983121c4f4b6b785c4db0d5606916140..35cf10864128be07161f13d6a8895ef0c7a01792 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -81,8 +81,9 @@ flushmmu(void) void kmapinit(void) { + int i; + Page *p; KMap *k; - int i, e; if(kmapalloc.init == 0){ k = &kmapalloc.arena[0]; @@ -93,16 +94,17 @@ kmapinit(void) return; } - e = (MB4 - 256*1024)/BY2PG; /* screen lives at top 256K */ - i = PGROUND(palloc.addr0)/BY2PG; - - print("%lud free map registers\n", e-i); - - kmapalloc.free = 0; - for(k=&kmapalloc.arena[i]; i < e; i++){ - k->va = i*BY2PG|KZERO; - kunmap(k++); + i = 0; + /* Reclaim map register for pages in bank0 */ + for(p = palloc.head; p; p = p->next) { + if(p->pa < MB4) { + k = &kmapalloc.arena[p->pa/BY2PG]; + k->va = p->pa|KZERO; + kunmap(k); + i++; + } } + print("%lud free map registers\n", i); } KMap* diff --git a/gnot/trap.c b/gnot/trap.c index c3c956b3a65a7e100e150de8f8fe357b496a339d..f59f2020cd4904952dc49630c4160329aa0077ab 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -278,7 +278,6 @@ syscall(Ureg *aur) ulong sp; ulong r0; Ureg *ur; - char *msg; u->p->insyscall = 1; ur = aur; @@ -310,22 +309,24 @@ syscall(Ureg *aur) ret = -1; if(!waserror()){ if(r0 >= sizeof systab/sizeof systab[0]){ - pprint("bad sys call number %d pc %lux\n", r0, ((Ureg*)UREGADDR)->pc); - msg = "sys: bad sys call"; - Bad: - postnote(u->p, 1, msg, NDebug); + pprint("bad sys call number %d pc %lux\n", r0, ur->pc); + postnote(u->p, 1, "sys: bad sys call", NDebug); error(Ebadarg); } + if(sp & (BY2WD-1)){ - pprint("odd sp in sys call pc %lux sp %lux\n", - ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - msg = "sys: odd stack"; - goto Bad; + pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp); + postnote(u->p, 1, "sys: odd stack", NDebug); + error(Ebadarg); } - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) - validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); + + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) + validaddr(sp, sizeof(Sargs), 0); + + u->s = *((Sargs*)(sp+BY2WD)); u->p->psstate = sysctab[r0]; - ret = (*systab[r0])((ulong*)(sp+BY2WD)); + + ret = (*systab[r0])(u->s.args); poperror(); } diff --git a/pc/dat.h b/pc/dat.h index 98f281fba1fdc81d8c4b4a804e436b5cf0af6646..fd36dc674ad10e5d415b388e51fdded2ddf7fac4 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -52,32 +52,13 @@ struct Conf { ulong nmach; /* processors */ ulong nproc; /* processes */ - ulong npgrp; /* process groups */ - ulong npage0; /* total physical pages in bank0 */ - ulong npage1; /* total physical pages in bank1 */ + ulong npage0; /* total physical pages of memory */ + ulong npage1; /* total physical pages of memory */ + ulong topofmem; /* highest physical address + 1 */ ulong npage; /* total physical pages of memory */ - ulong nseg; /* number of segments */ + ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ - ulong npagetab; /* number of pte tables */ ulong nswap; /* number of swap pages */ - ulong nalarm; /* alarms */ - ulong nchan; /* channels */ - ulong nenv; /* distinct environment values */ - ulong nenvchar; /* environment text storage */ - ulong npgenv; /* environment files per process group */ - ulong nmtab; /* mounted-upon channels per process group */ - ulong nmount; /* mounts */ - ulong nmntdev; /* mounted devices (devmnt.c) */ - ulong nmntbuf; /* buffers for devmnt.c messages */ - ulong nmnthdr; /* headers for devmnt.c messages */ - ulong nstream; /* streams */ - ulong nqueue; /* stream queues */ - ulong nblock; /* stream blocks */ - ulong nsrv; /* public servers (devsrv.c) */ - ulong nurp; /* max urp conversations */ - ulong nasync; /* number of async protocol modules */ - ulong npipe; /* number of pipes */ - ulong maxialloc; /* maximum bytes used by ialloc */ ulong base0; /* base of bank 0 */ ulong base1; /* base of bank 1 */ ulong copymode; /* 0 is copy on write, 1 is copy on reference */ @@ -88,7 +69,6 @@ struct Conf ulong cntrlp; /* panic on ^P */ ulong nfloppy; /* number of floppy drives */ ulong nhard; /* number of hard drives */ - int dkif; /* number of datakit interfaces */ }; /* @@ -151,6 +131,7 @@ struct User char elem[NAMELEN]; /* last name element from namec */ Chan *slash; Chan *dot; + Sargs s; /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/pc/devether.c b/pc/devether.c index f57409996ff21328a947d15e0d9d88cc4f8ae7f9..68f8d6f06c174ead05c1579159d26ed55777cbb2 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -59,6 +59,7 @@ enum { */ struct Type { QLock; + Netprot; /* stat info */ int type; /* ethernet type */ int prom; /* promiscuous mode */ Queue *q; @@ -96,7 +97,6 @@ struct Ctlr { uchar kproc; /* true if kproc started */ char name[NAMELEN]; /* name of kproc */ Network net; - Netprot prot[NType]; Queue lbq; /* software loopback packet queue */ @@ -331,7 +331,7 @@ etherstclose(Queue *q) tp->q = 0; tp->prom = 0; tp->inuse = 0; - netdisown(&tp->ctlr->net, tp - tp->ctlr->type); + netdisown(tp); tp->ctlr = 0; qunlock(tp); } @@ -357,7 +357,7 @@ clonecon(Chan *c) continue; } tp->inuse = 1; - netown(&cp->net, tp - cp->type, u->p->user, 0); + netown(tp, u->p->user, 0); qunlock(tp); return tp - cp->type; } @@ -483,8 +483,10 @@ etherkproc(void *arg) void etherreset(void) { - Ctlr *cp = &ctlr[0]; + int i; + Ctlr *cp; + cp = &ctlr[0]; cp->hw = &wd8013; (*cp->hw->reset)(cp); @@ -497,11 +499,12 @@ etherreset(void) cp->net.listen = 0; cp->net.clone = clonecon; cp->net.ninfo = 2; - cp->net.prot = cp->prot; cp->net.info[0].name = "stats"; cp->net.info[0].fill = statsfill; cp->net.info[1].name = "type"; cp->net.info[1].fill = typefill; + for(i = 0; i < NType; i++) + netadd(&cp->net, &cp->type[i], i); } void @@ -611,9 +614,9 @@ wd8013reset(Ctlr *cp) int i; uchar msr; - cp->rb = ialloc(sizeof(Buffer)*Nrb, 1); + cp->rb = xspanalloc(sizeof(Buffer)*Nrb, BY2PG, 0); cp->nrb = Nrb; - cp->tb = ialloc(sizeof(Buffer)*Ntb, 1); + cp->tb = xspanalloc(sizeof(Buffer)*Ntb, BY2PG, 0); cp->ntb = Ntb; msr = IN(hw, msr); diff --git a/pc/devfloppy.c b/pc/devfloppy.c index b8b88a35e01b365b822444584b7bd82cd594c946..8e21b0a1b5a8fdf92667330e51ff1e4c2053fc0b 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -212,7 +212,7 @@ floppyreset(void) /* * allocate the drive storage */ - fl.d = ialloc(conf.nfloppy*sizeof(Drive), 0); + fl.d = xalloc(conf.nfloppy*sizeof(Drive)); fl.selected = fl.d; /* @@ -231,7 +231,7 @@ floppyreset(void) dp->t = &floppytype[0]; /* default type */ floppydir[NFDIR*dp->dev].length = dp->t->cap; dp->cyl = -1; /* because we don't know */ - dp->cache = (uchar*)ialloc(dp->t->tsize, 1); + dp->cache = (uchar*)xspanalloc(dp->t->tsize, BY2PG, 0); dp->ccyl = -1; dp->vers = 1; } diff --git a/pc/devhard.c b/pc/devhard.c index 02aab770f677b4796e3230108fd263a7cef1732a..bb2887934368685c2c3fb11db797a71a46bc1f02 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -201,8 +201,8 @@ hardreset(void) Controller *cp; int drive; - hard = ialloc(conf.nhard * sizeof(Drive), 0); - hardc = ialloc(((conf.nhard+1)/2 + 1) * sizeof(Controller), 0); + hard = xalloc(conf.nhard * sizeof(Drive)); + hardc = xalloc(((conf.nhard+1)/2 + 1) * sizeof(Controller)); for(drive = 0; drive < conf.nhard; drive++){ dp = &hard[drive]; @@ -211,7 +211,7 @@ hardreset(void) dp->online = 0; dp->cp = cp; if((drive&1) == 0){ - cp->buf = ialloc(Maxxfer, 0); + cp->buf = xalloc(Maxxfer); cp->lastcmd = cp->cmd; cp->cmd = 0; cp->pbase = Pbase + (cp-hardc)*8; /* BUG!! guessing */ diff --git a/pc/devincon.c b/pc/devincon.c index 06a2a742983812b395be2ddb22e67941d652be34..adc19857bb940556a61aad6a498d808cbd69dfd7 100644 --- a/pc/devincon.c +++ b/pc/devincon.c @@ -579,7 +579,7 @@ inconread(Chan *c, void *buf, long n, ulong offset) sprint(b, "%d\n", incondebug); break; } - return stringread(buf, n, b, offset); + return readstr(offset, buf, n, b); } long diff --git a/pc/devuart.c b/pc/devuart.c index 45ab9fcedc22221315bfe84a8a2e1c09fc84a5bf..0567254e16c25baa91c5d3f32e7cf5fd85cd7cac 100644 --- a/pc/devuart.c +++ b/pc/devuart.c @@ -578,9 +578,9 @@ uartreset(void) for(up = uart; up < &uart[2]; up++){ if(up->nostream) continue; - up->iq = ialloc(sizeof(IOQ), 0); + up->iq = xalloc(sizeof(IOQ)); initq(up->iq); - up->oq = ialloc(sizeof(IOQ), 0); + up->oq = xalloc(sizeof(IOQ)); initq(up->oq); } } diff --git a/pc/fns.h b/pc/fns.h index 0b54a7c2433acb57f63572d7b356c00d0ac897b3..ac6cbfc7906e310243580d89571924f36a76135a 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -68,3 +68,5 @@ void vgainit(void); #define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) #define kmapperm(x) kmap(x) #define getcallerpc(x) (*(ulong*)(x)) +#define KADDR(a) ((void*)((ulong)(a)|KZERO)) +#define PADDR(a) ((ulong)(a)&~KZERO) diff --git a/pc/main.c b/pc/main.c index c3ef01765fc6bf8fe940abff1faf7af1f36863b4..7797e167dd6a3232d1efe7c31975c42fdff36d4a 100644 --- a/pc/main.c +++ b/pc/main.c @@ -19,10 +19,11 @@ main(void) active.exiting = 0; active.machs = 1; confinit(); + xinit(); screeninit(); printinit(); - print("%ludK bytes of physical memory\n", (conf.base1 + conf.npage1*BY2PG)/1024); mmuinit(); + pageinit(); trapinit(); mathinit(); clockinit(); @@ -30,12 +31,9 @@ main(void) kbdinit(); procinit0(); initseg(); - grpinit(); - chaninit(); chandevreset(); streaminit(); swapinit(); - pageinit(); userinit(); schedinit(); @@ -107,8 +105,10 @@ userinit(void) p = newproc(); p->pgrp = newpgrp(); - p->egrp = newegrp(); - p->fgrp = newfgrp(); + p->egrp = smalloc(sizeof(Egrp)); + p->egrp->ref = 1; + p->fgrp = smalloc(sizeof(Fgrp)); + p->fgrp->ref = 1; p->procmode = 0640; strcpy(p->text, "*init*"); @@ -219,52 +219,35 @@ confinit(void) /* * write the word */ - l = (long*)(KZERO|(i*1024L*1024L)); + l = (long*)(KZERO|(i*MB)); *l = x; /* * take care of wraps */ for(j = 0; j < i; j++){ - l = (long*)(KZERO|(j*1024L*1024L)); + l = (long*)(KZERO|(j*MB)); *l = 0; } /* * check */ - l = (long*)(KZERO|(i*1024L*1024L)); + l = (long*)(KZERO|(i*MB)); if(*l != x) break; x += 0x3141526; } - conf.base1 = 0x100000; - conf.npage1 = ((i-1)*1024*1024 - conf.base1)/BY2PG; - + conf.base1 = 1*MB; + conf.npage1 = ((i-1)*MB - conf.base1)/BY2PG; conf.npage = conf.npage0 + conf.npage1; + conf.upages = (conf.npage*70)/100; + + /* for meminit() */ + conf.topofmem = i*MB; mul = 1; conf.nproc = 30 + i*5; - conf.npgrp = conf.nproc/2; - conf.nseg = conf.nproc*3; - conf.npagetab = (conf.nseg*14)/10; conf.nswap = conf.nproc*80; conf.nimage = 50; - conf.nalarm = 1000; - conf.nchan = 6*conf.nproc; - conf.nenv = 4*conf.nproc; - conf.nenvchar = 8000*mul; - conf.npgenv = 200*mul; - conf.nmtab = 50*mul; - conf.nmount = 80*mul; - conf.nmntdev = 15*mul; - conf.nmntbuf = conf.nmntdev+3; - conf.nmnthdr = 2*conf.nmntdev; - conf.nsrv = 16*mul; /* was 32 */ - conf.nurp = 32; - conf.nasync = 1; - conf.nstream = (conf.nproc*3)/2; - conf.nqueue = 5 * conf.nstream; - conf.nblock = 24 * conf.nstream; - conf.npipe = conf.nstream/2; conf.copymode = 0; /* copy on write */ conf.ipif = 8; conf.ip = 64; @@ -273,7 +256,7 @@ confinit(void) conf.cntrlp = 0; conf.nfloppy = 2; conf.nhard = 1; - conf.dkif = 1; + confinit1(mul); } diff --git a/pc/mem.h b/pc/mem.h index 78ed71ece5fc33c4d0dbb33ecaff4c9fbe14c5e6..f79cc370887f213c561103462f08babad2d90417 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -12,6 +12,7 @@ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 12 /* log(BY2PG) */ #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) +#define MB (1024*1024) #define MAXMACH 1 /* max # cpus system can run */ diff --git a/pc/mmu.c b/pc/mmu.c index 666a51aa5d9af35b1b69a73e7a5455e69d827583..f08638f743ee4760f82063460819915aa422942f 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -117,15 +117,15 @@ mmuinit(void) */ /* allocate top level table */ - top = ialloc(BY2PG, 1); + top = xspanalloc(BY2PG, BY2PG, 0); ktoppg.va = (ulong)top; ktoppg.pa = ktoppg.va & ~KZERO; /* map all memory to KZERO */ - npage = conf.base1/BY2PG + conf.npage1; + npage = conf.topofmem/BY2PG; nbytes = PGROUND(npage*BY2WD); /* words of page map */ nkpt = nbytes/BY2PG; /* pages of page map */ - kpt = ialloc(nbytes, 1); + kpt = xspanalloc(nbytes, BY2PG, 0); for(i = 0; i < npage; i++) kpt[i] = (0+i*BY2PG) | PTEVALID | PTEKERNEL | PTEWRITE; x = TOPOFF(KZERO); @@ -134,7 +134,7 @@ mmuinit(void) top[x+i] = (y+i*BY2PG) | PTEVALID | PTEKERNEL | PTEWRITE; /* page table for u-> */ - upt = ialloc(BY2PG, 1); + upt = xspanalloc(BY2PG, BY2PG, 0); x = TOPOFF(USERADDR); y = ((ulong)upt)&~KZERO; top[x] = y | PTEVALID | PTEKERNEL | PTEWRITE; diff --git a/pc/trap.c b/pc/trap.c index b33b38c2764652b0e0ce176cbebb61141304695d..faa63cf2c153eb4c99c9e4641a3fc2c8a2922214 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -328,10 +328,14 @@ syscall(Ureg *ur) postnote(u->p, 1, "sys: bad sys call", NDebug); error(Ebadarg); } + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); + + u->s = *((Sargs*)(sp+1*BY2WD)); u->p->psstate = sysctab[ax]; - ret = (*systab[ax])((ulong*)(sp+BY2WD)); + + ret = (*systab[ax])(u->s.args); poperror(); } if(u->nerrlab){ diff --git a/port/alloc.c b/port/alloc.c index c8ebcc3c7372618e82be0feb7407bf591403b39b..fdb25ce2d695fb1ebc4e8303899e84e03b04f28f 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -68,6 +68,8 @@ struct Arena Lock; Bucket *btab[Maxpow]; int nbuck[Maxpow]; + QLock rq; + Rendez r; }; static Arena arena; @@ -100,6 +102,7 @@ xinit(void) conf.base1 += np1*BY2PG; conf.npage1 -= np1; xhole(conf.base1, conf.npage1*BY2PG); + conf.npage1 = conf.base1+(conf.npage1*BY2PG); up -= np1; np0 = up; @@ -110,9 +113,15 @@ xinit(void) conf.base0 += np0*BY2PG; conf.npage0 -= np0; xhole(conf.base0, conf.npage0*BY2PG); + conf.npage0 = conf.base0+(conf.npage0*BY2PG); palloc.np0 = np0; palloc.np1 = np1; + /* Save the bounds of kernel alloc memory for kernel mmu mapping (NeXT) */ + conf.base0 = (ulong)KADDR(conf.base0); + conf.base1 = (ulong)KADDR(conf.base1); + conf.npage0 = (ulong)KADDR(conf.npage0); + conf.npage1 = (ulong)KADDR(conf.npage1); } /* @@ -287,13 +296,22 @@ good: void* smalloc(ulong size) { + char *s; void *p; - p = malloc(size); - if(p == nil) { - print("asking for %d\n", size); - xsummary(); - panic("smalloc should sleep"); + for(;;) { + p = malloc(size); + if(p != nil) + return p; + s = u->p->psstate; + u->p->psstate = "Malloc"; + qlock(&arena.rq); + while(waserror()) + ; + sleep(&arena.r, return0, nil); + poperror(); + qunlock(&arena.rq); + u->p->psstate = s; } return p; } @@ -324,6 +342,8 @@ free(void *ptr) bp->next = *l; *l = bp; unlock(&arena); + if(arena.r.p) + wakeup(&arena.r); } void diff --git a/port/devboot.c b/port/devboot.c index f27b877f372af3f69c124d97f84d2d125343b2fb..f1b8fd02b255cc3c3655b3ad5685b666c6fbee1b 100644 --- a/port/devboot.c +++ b/port/devboot.c @@ -76,8 +76,19 @@ long bootread(Chan *c, void *buf, long n, ulong offset) { switch(c->qid.path & ~CHDIR){ + case Qdir: return devdirread(c, buf, n, bootdir, NBOOT, devgen); + + case Qmem: + /* kernel memory */ + if(offset>=KZERO && offset KZERO+conf.npage*BY2PG) + n = KZERO+conf.npage*BY2PG - offset; + memmove(buf, (char*)offset, n); + return n; + } + error(Ebadarg); } error(Egreg); @@ -93,13 +104,11 @@ bootwrite(Chan *c, void *buf, long n, ulong offset) case Qmem: /* kernel memory */ if(offset>=KZERO && offsetoffset, n);/**/ if(offset+n > KZERO+conf.npage*BY2PG) n = KZERO+conf.npage*BY2PG - offset; memmove((char*)offset, buf, n); return n; } - print("bootwrite: bad addr %lux\n", offset); error(Ebadarg); case Qboot: @@ -107,7 +116,6 @@ bootwrite(Chan *c, void *buf, long n, ulong offset) splhi(); gotopc(pc); } - print("bootwrite: bad path %d\n", c->qid.path); error(Ebadarg); return 0; /* not reached */ } diff --git a/port/devdk.c b/port/devdk.c index 1a4181258a2065ce0d0b47f08f6e020d0d3247ac..26deeb8b0226f892d7beda74e7ea3efae53ef106 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -104,30 +104,27 @@ struct Line { * a dkmux dk. one exists for every stream that a * dkmux line discipline is pushed onto. */ -struct Dk { +struct Dk +{ QLock netlock; - Network net; + Network net; /* stat info */ + Line **linep; /* array of line structures */ QLock csclock; Chan *csc; - Lock; - int opened; - char name[64]; /* dk name */ Queue *wq; /* dk output queue */ - Stream *s; int ncsc; /* csc line number */ int lines; /* number of lines */ - Line **linep; int restart; int urpwindow; Rendez timer; int closeall; /* set when we receive a closeall message */ Rendez closeallr; /* wait here for a closeall */ }; -static Dk *dk; -static Lock dklock; +Lock dklock; +Dk *dk[Maxdk]; /* * conversation states (for Line.state) @@ -207,9 +204,9 @@ extern Qinfo dkinfo; /* * the datakit multiplexor stream module definition */ -static void dkmuxopen(Queue *, Stream *); -static void dkmuxoput(Queue *, Block *); -static void dkmuxiput(Queue *, Block *); +static Streamopen dkmuxopen; +static Streamput dkmuxoput; +static Streamput dkmuxiput; Qinfo dkmuxinfo = { dkmuxiput, @@ -219,70 +216,6 @@ Qinfo dkmuxinfo = "dkmux" }; -/* - * Look for a dk struct with a name. If none exists, create one. - */ -static Dk* -dkalloc(char *name, int ncsc, int lines) -{ - Dk *dp; - Dk *freep; - int i, n; - Line *lp; - - lock(&dklock); - freep = 0; - for(dp = dk; dp < &dk[Maxdk]; dp++){ - if(strcmp(name, dp->name) == 0){ - unlock(&dklock); - return dp; - } - if(dp->name[0] == 0) - freep = dp; - } - if(freep == 0 || lines == 0){ - unlock(&dklock); - error(Enoifc); - } - - dp = freep; - dp->opened = 0; - dp->s = 0; - dp->ncsc = ncsc; - dp->lines = lines; - strncpy(dp->name, name, sizeof(freep->name)); - - /* - * allocate memory for array of pointers to lines. - * line structures are allocated as needed. - */ - dp->linep = smalloc(sizeof(Line*) * dp->lines); - - /* - * fill in the network structure - */ - dp->net.name = dp->name; - dp->net.nconv = dp->lines; - dp->net.devp = &dkinfo; - dp->net.protop = &urpinfo; - dp->net.listen = dklisten; - dp->net.clone = dkcloneline; - dp->net.ninfo = 5; - dp->net.info[0].name = "addr"; - dp->net.info[0].fill = dkfilladdr; - dp->net.info[1].name = "raddr"; - dp->net.info[1].fill = dkfillraddr; - dp->net.info[2].name = "ruser"; - dp->net.info[2].fill = dkfillruser; - dp->net.info[3].name = "stats"; - dp->net.info[3].fill = urpfillstats; - dp->net.info[4].name = "other"; - dp->net.info[4].fill = dkfillother; - - unlock(&dklock); - return dp; -} - /* * allocate a line if it doesn't exist */ @@ -291,8 +224,6 @@ linealloc(Dk *dp, int lineno, int dolock) { Line *lp; - if(dp->opened == 0) - error(Enoifc); if(dolock) qlock(&dp->netlock); if(lineno > dp->lines) @@ -315,11 +246,10 @@ linealloc(Dk *dp, int lineno, int dolock) static void dkmuxopen(Queue *q, Stream *s) { - RD(q)->ptr = s; + RD(q)->ptr = 0; WR(q)->ptr = 0; - s->opens++; /* Hold this queue in place */ - s->inuse++; + naildownstream(s); } /* @@ -395,10 +325,9 @@ dkmuxiput(Queue *q, Block *bp) /* * the datakit line stream module definition */ -static void dkstopen(Queue *, Stream *); -static void dkstclose(Queue *); -static void dkoput(Queue *, Block *); -static void dkiput(Queue *, Block *); +static Streamopen dkstopen; +static Streamclose dkstclose; +static Streamput dkoput, dkiput; Qinfo dkinfo = { dkiput, @@ -417,7 +346,7 @@ dkstopen(Queue *q, Stream *s) Dk *dp; Line *lp; - dp = &dk[s->dev]; + dp = dk[s->dev]; q->other->ptr = q->ptr = lp = dp->linep[s->id]; lp->dp = dp; lp->rq = q; @@ -498,8 +427,6 @@ out: lp->rq = 0; qunlock(lp); - if(lp->lineno == dp->ncsc) - dp->csc = 0; netdisown(lp); lp->window = 0; } @@ -598,6 +525,7 @@ dkmuxconfig(Queue *q, Block *bp) window = strtoul(fields[4], 0, 0); case 4: strncpy(name, fields[3], sizeof(name)); + name[sizeof(name)-1] = 0; case 3: if(strcmp(fields[2], "restart")!=0) restart = 0; @@ -615,27 +543,62 @@ dkmuxconfig(Queue *q, Block *bp) error(Ebadarg); /* - * set up + * find a free dk slot. it name is already configured + * or no slots are left, error. */ - dp = dkalloc(name, ncsc, lines); - lock(dp); - if(dp->opened){ - unlock(dp); - error(Ebadarg); + lock(&dklock); + if(waserror()){ + unlock(&dklock); + nexterror(); } + for(n = 0; n < Maxdk; n++){ + dp = dk[n]; + if(dp == 0) + break; + if(strcmp(name, dp->name) == 0) + error(Einuse); + } + if(n == Maxdk) + error(Enoifc); + + /* + * allocate both a dk structure and an array of pointers to line + * structures + */ + dp = smalloc(sizeof(Dk)); + dp->ncsc = ncsc; + dp->lines = lines; + dp->linep = smalloc(sizeof(Line*) * dp->lines); + strcpy(dp->name, name); + dp->net.name = dp->name; + dp->net.nconv = dp->lines; + dp->net.devp = &dkinfo; + dp->net.protop = &urpinfo; + dp->net.listen = dklisten; + dp->net.clone = dkcloneline; + dp->net.ninfo = 5; + dp->net.info[0].name = "addr"; + dp->net.info[0].fill = dkfilladdr; + dp->net.info[1].name = "raddr"; + dp->net.info[1].fill = dkfillraddr; + dp->net.info[2].name = "ruser"; + dp->net.info[2].fill = dkfillruser; + dp->net.info[3].name = "stats"; + dp->net.info[3].fill = urpfillstats; + dp->net.info[4].name = "other"; + dp->net.info[4].fill = dkfillother; dp->restart = restart; dp->urpwindow = window; - dp->s = RD(q)->ptr; - q->ptr = q->other->ptr = dp; - dp->opened = 1; dp->wq = WR(q); - unlock(dp); + q->ptr = q->other->ptr = dp; + dk[n] = dp; + unlock(&dklock); + poperror(); /* * open csc here so that boot, dktimer, and dkcsckproc aren't * all fighting for it at once. */ - dp->closeall = 0; dkopencsc(dp); /* @@ -643,7 +606,6 @@ dkmuxconfig(Queue *q, Block *bp) */ sprint(buf, "csc.%s.%d", dp->name, dp->ncsc); kproc(buf, dkcsckproc, dp); - tsleep(&dp->closeallr, haveca, dp, 5000); /* wait for initial closeall */ /* * tell datakit we've rebooted. It should close all channels. @@ -653,8 +615,8 @@ dkmuxconfig(Queue *q, Block *bp) DPRINT("dktimer: restart %s\n", dp->name); dp->closeall = 0; dkmesg(dp->csc, T_ALIVE, D_RESTART, 0, 0); - tsleep(&dp->closeallr, haveca, dp, 5000); /* wait for restart closeall */ } + tsleep(&dp->closeallr, haveca, dp, 15000); /* * start a keepalive process @@ -666,9 +628,6 @@ dkmuxconfig(Queue *q, Block *bp) void dkreset(void) { - int i; - - dk = (Dk*)xalloc(Maxdk*sizeof(Dk)); newqinfo(&dkmuxinfo); } @@ -682,19 +641,26 @@ dkattach(char *spec) { Chan *c; Dk *dp; + int dev; /* * find a multiplexor with the same name (default dk) */ if(*spec == 0) spec = "dk"; - dp = dkalloc(spec, 0, 0); + for(dev = 0; dev < Maxdk; dev++){ + dp = dk[dev]; + if(dp && strcmp(dp->name, spec) == 0) + break; + } + if(dev == Maxdk) + error(Enoifc); /* * return the new channel */ c = devattach('k', spec); - c->dev = dp - dk; + c->dev = dev; return c; } @@ -707,13 +673,13 @@ dkclone(Chan *c, Chan *nc) int dkwalk(Chan *c, char *name) { - return netwalk(c, name, &dk[c->dev].net); + return netwalk(c, name, &dk[c->dev]->net); } void dkstat(Chan *c, char *dp) { - netstat(c, dp, &dk[c->dev].net); + netstat(c, dp, &dk[c->dev]->net); } Chan* @@ -721,7 +687,7 @@ dkopen(Chan *c, int omode) { Dk *dp; - dp = &dk[c->dev]; + dp = dk[c->dev]; linealloc(dp, STREAMID(c->qid.path), 1); return netopen(c, omode, &dp->net); } @@ -743,7 +709,7 @@ dkclose(Chan *c) long dkread(Chan *c, void *a, long n, ulong offset) { - return netread(c, a, n, offset, &dk[c->dev].net); + return netread(c, a, n, offset, &dk[c->dev]->net); } long @@ -813,7 +779,7 @@ dkremove(Chan *c) void dkwstat(Chan *c, char *dp) { - netwstat(c, dp, &dk[c->dev].net); + netwstat(c, dp, &dk[c->dev]->net); } /* @@ -826,7 +792,7 @@ dkcloneline(Chan *c) Dk *dp; int line; - dp = &dk[c->dev]; + dp = dk[c->dev]; /* * get an unused device and open its control file */ @@ -869,7 +835,7 @@ dkopenline(Dk *dp, int line) } /* - * open the common signalling channel + * open the common signalling channel (dp->csc's reference count never goes below 1) */ static Chan* dkopencsc(Dk *dp) @@ -879,8 +845,7 @@ dkopencsc(Dk *dp) qlock(&dp->csclock); if(dp->csc == 0) dp->csc = dkopenline(dp, dp->ncsc); - else - incref(dp->csc); + incref(dp->csc); qunlock(&dp->csclock); return dp->csc; } @@ -891,22 +856,22 @@ dkopencsc(Dk *dp) void dkfilladdr(Chan *c, char *buf, int len) { - strncpy(buf, dk[c->dev].linep[STREAMID(c->qid.path)]->addr, len); + strncpy(buf, dk[c->dev]->linep[STREAMID(c->qid.path)]->addr, len); } void dkfillraddr(Chan *c, char *buf, int len) { - strncpy(buf, dk[c->dev].linep[STREAMID(c->qid.path)]->raddr, len); + strncpy(buf, dk[c->dev]->linep[STREAMID(c->qid.path)]->raddr, len); } void dkfillruser(Chan *c, char *buf, int len) { - strncpy(buf, dk[c->dev].linep[STREAMID(c->qid.path)]->ruser, len); + strncpy(buf, dk[c->dev]->linep[STREAMID(c->qid.path)]->ruser, len); } void dkfillother(Chan *c, char *buf, int len) { - strncpy(buf, dk[c->dev].linep[STREAMID(c->qid.path)]->other, len); + strncpy(buf, dk[c->dev]->linep[STREAMID(c->qid.path)]->other, len); } /* @@ -963,7 +928,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine) char *bang, *dot; line = STREAMID(c->qid.path); - dp = &dk[c->dev]; + dp = dk[c->dev]; lp = linealloc(dp, line, 1); /* @@ -1139,7 +1104,7 @@ dklisten(Chan *c) Chan *dc; static int dts; - dp = &dk[c->dev]; + dp = dk[c->dev]; from = STREAMID(c->qid.path); /* @@ -1309,7 +1274,7 @@ dkanswer(Chan *c, int line, int code) Line *lp; Dk *dp; - dp = &dk[c->dev]; + dp = dk[c->dev]; lp = linealloc(dp, line, 1); /* @@ -1359,7 +1324,7 @@ dkwindow(Chan *c) long wins; Line *lp; - lp = linealloc(&dk[c->dev], STREAMID(c->qid.path), 1); + lp = linealloc(dk[c->dev], STREAMID(c->qid.path), 1); if(lp->window == 0) lp->window = 64; sprint(buf, "init %d %d", lp->window, Streamhi); @@ -1488,11 +1453,8 @@ dkchgmesg(Chan *c, Dk *dp, Dkmsg *dialp, int line) break; case D_ISCLOSED: /* acknowledging a local shutdown */ - if (line <= 0 || line >= dp->lines || (lp = dp->linep[line]) == 0) { - /* tell controller this line is not in use */ - dkmesg(c, T_CHG, D_CLOSE, line, 0); + if (line <= 0 || line >= dp->lines || (lp = dp->linep[line]) == 0) return; - } switch (lp->state) { case Llclose: case Lclosed: diff --git a/port/devenv.c b/port/devenv.c index 9f21e238b6563a01e853e79bfb6bd68a8852645b..00de34b596c257754d63ac10c0e32333a7e82422 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -76,7 +76,7 @@ envopen(Chan *c, int omode) Evalue *e; eg = u->p->egrp; - if(c->qid.path & CHDIR){ + if(c->qid.path & CHDIR) { if(omode != OREAD) error(Eperm); } @@ -256,6 +256,46 @@ envwrite(Chan *c, void *a, long n, ulong offset) return n; } +void +envcpy(Egrp *to, Egrp *from) +{ + Evalue **l, *ne, *e; + + l = &to->entries; + qlock(from); + for(e = from->entries; e; e = e->link) { + ne = smalloc(sizeof(Evalue)); + ne->name = smalloc(strlen(e->name)+1); + strcpy(ne->name, e->name); + if(e->value) { + ne->value = smalloc(e->len); + memmove(ne->value, e->value, e->len); + ne->len = e->len; + } + ne->path = ++to->path; + *l = ne; + l = &ne->link; + } + qunlock(from); +} + +void +closeegrp(Egrp *eg) +{ + Evalue *e, *next; + + if(decref(eg) == 0) { + for(e = eg->entries; e; e = next) { + next = e->link; + free(e->name); + if(e->value) + free(e->value); + free(e); + } + free(eg); + } +} + /* * to let the kernel set environment variables */ diff --git a/port/devip.c b/port/devip.c index 13a14675ee2a8d83ce7315f4ad02a375ce8078fe..f06b61be933286c8e2796f59aa24e4eb744598d9 100644 --- a/port/devip.c +++ b/port/devip.c @@ -23,26 +23,9 @@ Network *ipnet[Nrprotocol]; /* User level interface for protocol */ QLock ipalloc; /* Protocol port allocation lock */ Ipconv *tcpbase; /* Base tcp connection */ -/* ARPA User Datagram Protocol */ -void udpstiput(Queue *, Block *); -void udpstoput(Queue *, Block *); -void udpstopen(Queue *, Stream *); -void udpstclose(Queue *); -/* ARPA Transmission Control Protocol */ -void tcpstiput(Queue *, Block *); -void tcpstoput(Queue *, Block *); -void tcpstopen(Queue *, Stream *); -void tcpstclose(Queue *); -/* Plan9 Reliable Datagram Protocol */ -void iliput(Queue *, Block *); -void iloput(Queue *, Block *); -void ilopen(Queue *, Stream *); -void ilclose(Queue *); -/* BSD authentication Protocol checker */ -void bsdiput(Queue *, Block *); -void bsdoput(Queue *, Block *); -void bsdopen(Queue *, Stream *); -void bsdclose(Queue *); +Streamput udpstiput, udpstoput, tcpstiput, tcpstoput, iliput, iloput, bsdiput, bsdoput; +Streamopen udpstopen, tcpstopen, ilopen, bsdopen; +Streamclose udpstclose, tcpstclose, ilclose, bsdclose; Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp", 0, 1 }; Qinfo udpinfo = { udpstiput, udpstoput, udpstopen, udpstclose, "udp" }; diff --git a/port/devpipe.c b/port/devpipe.c index 34602a64dfbbe85af66d1f0d15d89e0a9cd3e9fb..f7e63bd4f6cc191ab324c40beda7fe08e9a16e26 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -229,7 +229,7 @@ pipeclose(Chan *c) *l = p->next; break; } - l = &p->next; + l = &f->next; } unlock(&pipealloc); free(p); @@ -319,6 +319,6 @@ getpipe(ulong path) } } unlock(&pipealloc); - error(Enonexist); - return 0; + panic("getpipe"); + return 0; /* not reached */ } diff --git a/port/devscsi.c b/port/devscsi.c index c0750da0fc5bafa97d0c668e0b8a6e43fbe24071..bb9977aa1a26e1062e4ea5ff12ecd3d723f7fb24 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -51,11 +51,6 @@ struct Scsi uchar cmdblk[16]; }; -struct{ - Lock; - Scsibuf *free; -}scsibufalloc; - static Scsi staticcmd; /* BUG: should be one per scsi device */ enum @@ -464,22 +459,6 @@ scsibwrite(int dev, Scsibuf *b, long n, long blocksize, long blockno) return n; } -/* - * allocate a scsi buf of any length - * must be called at ialloc time and never freed - */ -Scsibuf * -scsialloc(ulong n) -{ - Scsibuf *b; - uchar *x; - long m; - - b = ialloc(sizeof *b, 0); - b->virt = b->phys = ialloc(n, 0); - return b; -} - /* * get a scsi io buffer of DATASIZE size */ @@ -488,26 +467,16 @@ scsibuf(void) { Scsibuf *b; - for(;;) { - lock(&scsibufalloc); - if(b = scsibufalloc.free) { - scsibufalloc.free = b->next; - unlock(&scsibufalloc); - return b; - } - - unlock(&scsibufalloc); - resrcwait("no scsi buffers"); - } + b = smalloc(sizeof(Scsibuf)+DATASIZE); + b->phys = (void*)(b + 1); + b->virt = b->phys; + return b; } void scsifree(Scsibuf *b) { - lock(&scsibufalloc); - b->next = scsibufalloc.free; - scsibufalloc.free = b; - unlock(&scsibufalloc); + free(b); } typedef struct Scsictl { @@ -567,15 +536,7 @@ nop(void) void scsireset(void) { - static int alloced = 0; - int i; - addportintr(scsiintr); - if(!alloced){ - for(i = 0; i < Nbuf; i++) - scsifree(scsialloc(DATASIZE)); - alloced = 1; - } } void diff --git a/port/fault.c b/port/fault.c index dd98e57d9c7b8c96f11da3ece5ba69b9df4a2425..5f80f1e38b540817a9479baf942c493430a3dc01 100644 --- a/port/fault.c +++ b/port/fault.c @@ -112,9 +112,9 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) } lkp = *pg; - lockpage(lkp); + lock(lkp); if(lkp->ref > 1) { - unlockpage(lkp); + unlock(lkp); if(new == 0) if(new = newpage(0, &s, addr)) if(s == 0) @@ -129,7 +129,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) if(lkp->image) duppage(lkp); - unlockpage(lkp); + unlock(lkp); } done: mmuphys = PPN((*pg)->pa) | PTEWRITE|PTEVALID; diff --git a/port/ipdat.h b/port/ipdat.h index 50ebf5e06a3602c070c74d5eea813c02ab61e42e..8024da707de39b750c63a03addb11049fc133d22 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -1,18 +1,18 @@ -typedef struct Ipconv Ipconv; -typedef struct Ipifc Ipifc; +typedef struct Etherhdr Etherhdr; typedef struct Fragq Fragq; -typedef struct Ipfrag Ipfrag; +typedef struct Ilcb Ilcb; +typedef struct Ilhdr Ilhdr; typedef ulong Ipaddr; +typedef struct Ipconv Ipconv; +typedef struct Ipfrag Ipfrag; +typedef struct Ipifc Ipifc; typedef ushort Port; -typedef struct Udphdr Udphdr; -typedef struct Etherhdr Etherhdr; typedef struct Reseq Reseq; typedef struct Tcp Tcp; typedef struct Tcpctl Tcpctl; typedef struct Tcphdr Tcphdr; typedef struct Timer Timer; -typedef struct Ilhdr Ilhdr; -typedef struct Ilcb Ilcb; +typedef struct Udphdr Udphdr; struct Etherhdr { @@ -94,40 +94,40 @@ struct Ilhdr uchar ilack[4]; /* Acked sequence */ }; -struct Ilcb /* Control block */ +struct Ilcb /* Control block */ { - int state; /* Connection state */ + int state; /* Connection state */ - Rendez syncer; /* where syncer waits for a connect */ + Rendez syncer; /* where syncer waits for a connect */ - QLock ackq; /* Unacknowledged queue */ + QLock ackq; /* Unacknowledged queue */ Block *unacked; Block *unackedtail; - QLock outo; /* Out of order packet queue */ + QLock outo; /* Out of order packet queue */ Block *outoforder; Lock nxl; - ulong next; /* Id of next to send */ - ulong recvd; /* Last packet received */ - ulong start; /* Local start id */ - ulong rstart; /* Remote start id */ - - int timeout; /* Time out counter */ - int slowtime; /* Slow time counter */ - int fasttime; /* Retransmission timer */ - int acktime; /* Acknowledge timer */ - int querytime; /* Query timer */ - int deathtime; /* Time to kill connection */ - - int rtt; /* Average round trip time */ - ulong rttack; /* The ack we are waiting for */ - ulong ackms; /* Time we issued */ - - int window; /* Maximum receive window */ + ulong next; /* Id of next to send */ + ulong recvd; /* Last packet received */ + ulong start; /* Local start id */ + ulong rstart; /* Remote start id */ + + int timeout; /* Time out counter */ + int slowtime; /* Slow time counter */ + int fasttime; /* Retransmission timer */ + int acktime; /* Acknowledge timer */ + int querytime; /* Query timer */ + int deathtime; /* Time to kill connection */ + + int rtt; /* Average round trip time */ + ulong rttack; /* The ack we are waiting for */ + ulong ackms; /* Time we issued */ + + int window; /* Maximum receive window */ }; -enum /* Packet types */ +enum /* Packet types */ { Ilsync, Ildata, @@ -138,7 +138,7 @@ enum /* Packet types */ Ilclose, }; -enum /* Connection state */ +enum /* Connection state */ { Ilclosed, Ilsyncer, @@ -204,46 +204,46 @@ struct Tctl uchar type; /* Listening or active connection */ uchar code; /* Icmp code */ struct { - int una; /* Unacked data pointer */ - int nxt; /* Next sequence expected */ - int ptr; /* Data pointer */ - ushort wnd; /* Tcp send window */ - int up; /* Urgent data pointer */ - int wl1; - int wl2; + int una; /* Unacked data pointer */ + int nxt; /* Next sequence expected */ + int ptr; /* Data pointer */ + ushort wnd; /* Tcp send window */ + int up; /* Urgent data pointer */ + int wl1; + int wl2; } snd; + struct { + int nxt; + ushort wnd; + int up; + } rcv; int iss; ushort cwind; ushort ssthresh; int resent; - struct { - int nxt; - ushort wnd; - int up; - } rcv; int irs; ushort mss; int rerecv; ushort window; int max_snd; - int last_ack; + int last_ack; /* Last acknowledege received */ char backoff; - char flags; - char tos; + char flags; /* State flags */ + char tos; /* Type of service */ - Blist rcvq; + Blist rcvq; /* Received data */ ulong rcvcnt; - Block *sndq; /* List of data going out */ - ulong sndcnt; /* Amount of data in send queue */ + Block *sndq; /* List of data going out */ + ulong sndcnt; /* Amount of data in send queue */ - Reseq *reseq; /* Resequencing queue */ + Reseq *reseq; /* Resequencing queue */ Timer timer; - Timer acktimer; /* Acknoledge timer */ - Timer rtt_timer; /* Round trip timer */ - int rttseq; /* Round trip sequence */ - int srtt; /* Shortened round trip */ - int mdev; /* Mean deviation of round trip */ + Timer acktimer; /* Acknoledge timer */ + Timer rtt_timer; /* Round trip timer */ + int rttseq; /* Round trip sequence */ + int srtt; /* Shortened round trip */ + int mdev; /* Mean deviation of round trip */ }; struct Tcpctl @@ -277,77 +277,77 @@ struct Reseq /* An ip interface used for UDP/TCP/IL */ struct Ipconv { - QLock; /* Ref count lock */ - Netprot; /* stat info */ + QLock; /* Ref count lock */ + Netprot; /* stat info */ int ref; - Qinfo *stproto; /* Stream protocol for this device */ - Network *net; /* user level network interface */ - Ipaddr dst; /* Destination from connect */ - Port psrc; /* Source port */ - Port pdst; /* Destination port */ - - Ipifc *ipinterface; /* Ip protocol interface */ - Queue *readq; /* Pointer to upstream read q */ - QLock listenq; /* List of people waiting incoming cons */ - Rendez listenr; /* Some where to sleep while waiting */ + Qinfo *stproto; /* Stream protocol for this device */ + Network *net; /* user level network interface */ + Ipaddr dst; /* Destination from connect */ + Port psrc; /* Source port */ + Port pdst; /* Destination port */ + + Ipifc *ipinterface; /* Ip protocol interface */ + Queue *readq; /* Pointer to upstream read q */ + QLock listenq; /* List of people waiting incoming cons */ + Rendez listenr; /* Some where to sleep while waiting */ - char *err; /* Async protocol error */ - int backlog; /* Maximum number of waiting connections */ - int curlog; /* Number of waiting connections */ - Ipconv *newcon; /* Flags that this is the start of a connection */ + char *err; /* Async protocol error */ + int backlog; /* Maximum number of waiting connections */ + int curlog; /* Number of waiting connections */ + Ipconv *newcon; /* This is the start of a connection */ union { - Tcpctl tcpctl; /* Tcp control block */ - Ilcb ilctl; /* Il control block */ + Tcpctl tcpctl; /* Tcp control block */ + Ilcb ilctl; /* Il control block */ }; }; -#define MAX_TIME 100000000 /* Forever */ -#define TCP_ACK 200 /* Timed ack sequence every 200ms */ - -#define URG 0x20 -#define ACK 0x10 -#define PSH 0x08 -#define RST 0x04 -#define SYN 0x02 -#define FIN 0x01 - -#define EOL_KIND 0 -#define NOOP_KIND 1 -#define MSS_KIND 2 - -#define MSS_LENGTH 4 -#define MSL2 10 -#define MSPTICK 100 -#define DEF_MSS 1024 -#define DEF_RTT 1000 - -#define TCP_PASSIVE 0 -#define TCP_ACTIVE 1 -#define IL_PASSIVE 0 -#define IL_ACTIVE 1 - -#define MAXBACKOFF 5 -#define FORCE 1 -#define CLONE 2 -#define RETRAN 4 -#define ACTIVE 8 -#define SYNACK 16 -#define AGAIN 8 -#define DGAIN 4 - -#define TIMER_STOP 0 -#define TIMER_RUN 1 -#define TIMER_EXPIRE 2 - -#define Nreseq 128 +enum { + MAX_TIME = (1<<20),/* Forever */ + TCP_ACK = 200, /* Timed ack sequence every 200ms */ + + URG = 0x20, /* Data marked urgent */ + ACK = 0x10, /* Aknowledge is valid */ + PSH = 0x08, /* Whole data pipe is pushed */ + RST = 0x04, /* Reset connection */ + SYN = 0x02, /* Pkt. is synchronise */ + FIN = 0x01, /* Start close down */ + + EOL_KIND = 0, + NOOP_KIND = 1, + MSS_KIND = 2, + + MSS_LENGTH = 4, /* Mean segment size */ + MSL2 = 10, + MSPTICK = 100, /* Milliseconds per timer tick */ + DEF_MSS = 1024, /* Default mean segment */ + DEF_RTT = 1000, /* Default round trip */ + + TCP_PASSIVE = 0, /* Listen connection */ + TCP_ACTIVE = 1, /* Outgoing connection */ + IL_PASSIVE = 0, + IL_ACTIVE = 1, + + MAXBACKOFF = 5, + FORCE = 1, + CLONE = 2, + RETRAN = 4, + ACTIVE = 8, + SYNACK = 16, + AGAIN = 8, + DGAIN = 4, + + TIMER_STOP = 0, + TIMER_RUN = 1, + TIMER_EXPIRE = 2, +}; #define set_timer(t,x) (((t)->start) = (x)/MSPTICK) #define run_timer(t) ((t)->state == TIMER_RUN) -enum /* Tcp connection states */ +enum /* Tcp connection states */ { - Closed = 0, + Closed = 0, Listen, Syn_sent, Syn_received, @@ -395,111 +395,100 @@ struct Ipfrag ushort flen; }; -#define IP_VER 0x40 /* Using IP version 4 */ -#define IP_HLEN 0x05 /* Header length in characters */ -#define IP_DF 0x4000 /* Don't fragment */ -#define IP_MF 0x2000 /* More fragments */ - -#define ICMP_ECHOREPLY 0 /* Echo Reply */ -#define ICMP_UNREACH 3 /* Destination Unreachable */ -#define ICMP_SOURCEQUENCH 4 /* Source Quench */ -#define ICMP_REDIRECT 5 /* Redirect */ -#define ICMP_ECHO 8 /* Echo Request */ -#define ICMP_TIMXCEED 11 /* Time-to-live Exceeded */ -#define ICMP_PARAMPROB 12 /* Parameter Problem */ -#define ICMP_TSTAMP 13 /* Timestamp */ -#define ICMP_TSTAMPREPLY 14 /* Timestamp Reply */ -#define ICMP_IREQ 15 /* Information Request */ -#define ICMP_IREQREPLY 16 /* Information Reply */ - -/* Sizes */ -#define IP_MAX (32*1024) /* Maximum Internet packet size */ -#define UDP_MAX (IP_MAX-ETHER_IPHDR) /* Maximum UDP datagram size */ -#define UDP_DATMAX (UDP_MAX-UDP_HDRSIZE) /* Maximum amount of udp data */ -#define IL_DATMAX (IP_MAX-IL_HDRSIZE) /* Maximum IL data in one ip packet */ - -/* Protocol numbers */ -#define IP_UDPPROTO 17 -#define IP_TCPPROTO 6 -#define IP_ILPROTO 40 - -/* Protocol port numbers */ -#define PORTALLOC 5000 /* First automatic allocated port */ -#define PRIVPORTALLOC 600 /* First priveleged port allocated */ -#define PORTMAX 30000 /* Last port to allocte */ - -/* IP function declarations */ -Ipifc *newipifc(uchar, void (*)(Ipconv *, Block*), Ipconv *, int, int, int, char*); +enum { + IP_VER = 0x40, /* Using IP version 4 */ + IP_HLEN = 0x05, /* Header length in characters */ + IP_DF = 0x4000, /* Don't fragment */ + IP_MF = 0x2000, /* More fragments */ + + /* Sizes */ + IP_MAX = (32*1024), /* Maximum Internet packet size */ + UDP_MAX = (IP_MAX-ETHER_IPHDR), /* Maximum UDP datagram size */ + UDP_DATMAX = (UDP_MAX-UDP_HDRSIZE),/* Maximum amount of udp data */ + IL_DATMAX = (IP_MAX-IL_HDRSIZE), /* Maximum IL data in one ip packet */ + + /* Protocol numbers */ + IP_UDPPROTO = 17, + IP_TCPPROTO = 6, + IP_ILPROTO = 40, + + /* Protocol port numbers */ + PORTALLOC = 5000, /* First automatic allocated port */ + PRIVPORTALLOC = 600, /* First priveleged port allocated */ + PORTMAX = 30000, /* Last port to allocte */ +}; + +void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort); +int arp_lookup(uchar*, uchar*); +int backoff(int); +Block* btrim(Block*, int, int); +void close_self(Ipconv *, char []); void closeipifc(Ipifc*); +int dupb(Block **, Block *, int, int); +void extract_oob(Block **, Block **, Tcp *); +void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *); +void hnputl(uchar*, ulong); +void hnputs(uchar*, ushort); +Block* htontcp(Tcp *, Block *, Tcphdr *); +Block* htontcp(Tcp *, Block *, Tcphdr *); +void iloutoforder(Ipconv*, Ilhdr*, Block*); +void ilstart(Ipconv *, int, int); +int inb_window(Tcpctl *, int); +void init_tcpctl(Ipconv *); +void initfrag(int); +Ipconv* ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto); ushort ip_csum(uchar*); -int arp_lookup(uchar*, uchar*); +Block* ip_reassemble(int, Block*, Etherhdr*); +int ipclonecon(Chan *); +int ipconbusy(Ipconv*); +int ipforme(uchar*); +Fragq* ipfragallo(void); +void ipfragfree(Fragq*, int); +Ipconv* ipincoming(Ipconv*, Ipconv*); +int iplisten(Chan *); +void iplocalfill(Chan*, char*, int); +void ipmkdir(Qinfo *, Dirtab *, Ipconv *); Ipaddr ipparse(char*); -void hnputs(uchar*, ushort); -void hnputl(uchar*, ulong); +void ipremotefill(Chan*, char*, int); +void iproute(uchar*, uchar*); +void ipsetaddrs(void); +void ipstatusfill(Chan*, char*, int); +Ipifc* newipifc(uchar, void (*)(Ipconv *, Block*), Ipconv *, int, int, int, char*); +Port nextport(Ipconv *, int); ulong nhgetl(uchar*); ushort nhgets(uchar*); -ushort ptcl_csum(Block*bp, int, int); -void ppkt(Block*); -void udprcvmsg(Ipconv *, Block*); -Block *btrim(Block*, int, int); -Block *ip_reassemble(int, Block*, Etherhdr*); -Ipconv *portused(Ipconv *, Port); -Port nextport(Ipconv *, int); -Fragq *ipfragallo(void); -void ipfragfree(Fragq*, int); -void iproute(uchar*, uchar*); -void initfrag(int); +int ntohtcp(Tcp *, Block **); int ntohtcp(Tcp*, Block**); -void reset(Ipaddr, Ipaddr, char, ushort, Tcp*); +Ipconv* portused(Ipconv *, Port); +void ppkt(Block*); void proc_syn(Ipconv*, char, Tcp*); +ushort ptcl_csum(Block*bp, int, int); +int pullb(Block **, int); +void reset(Ipaddr, Ipaddr, char, ushort, Tcp*); void send_syn(Tcpctl*); -void tcp_output(Ipconv*); -int seq_within(int, int, int); -void update(Ipconv *, Tcp *); -int trim(Tcpctl *, Tcp *, Block **, ushort *); -void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort); -void close_self(Ipconv *, char []); +int seq_ge(int, int); int seq_gt(int, int); -Ipconv *ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto); -void ipmkdir(Qinfo *, Dirtab *, Ipconv *); -Ipconv *ipincoming(Ipconv*, Ipconv*); -int inb_window(Tcpctl *, int); -Block *htontcp(Tcp *, Block *, Tcphdr *); -void start_timer(Timer *); -void stop_timer(Timer *); -int pullb(Block **, int); -void init_tcpctl(Ipconv *); -int seq_within(int, int, int); -int seq_lt(int, int); -int seq_le(int, int); int seq_gt(int, int); -int seq_ge(int, int); +int seq_le(int, int); +int seq_lt(int, int); +int seq_within(int, int, int); +int seq_within(int, int, int); void setstate(Ipconv *, char); -void tcpackproc(void*); -Block *htontcp(Tcp *, Block *, Tcphdr *); -int ntohtcp(Tcp *, Block **); -void extract_oob(Block **, Block **, Tcp *); -void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *); +void start_timer(Timer *); void state_upcall(Ipconv*, char oldstate, char newstate); -int backoff(int); -int dupb(Block **, Block *, int, int); +void stop_timer(Timer *); +void tcp_acktimer(void *); void tcp_input(Ipconv *, Block *); -void tcprcvwin(Ipconv *); -void tcpstart(Ipconv *, int, ushort, char); -void ilstart(Ipconv *, int, int); +void tcp_output(Ipconv*); +void tcp_timeout(void *); +void tcpackproc(void*); void tcpflow(void*); -void tcp_timeout(void *); -void tcp_acktimer(void *); -int ipclonecon(Chan *); -int iplisten(Chan *); -void iloutoforder(Ipconv*, Ilhdr*, Block*); -void iplocalfill(Chan*, char*, int); -void ipremotefill(Chan*, char*, int); -void ipstatusfill(Chan*, char*, int); -int ipforme(uchar*); -void ipsetaddrs(void); -int ipconbusy(Ipconv*); void tcpflushincoming(Ipconv*); +void tcprcvwin(Ipconv *); +void tcpstart(Ipconv *, int, ushort, char); +int trim(Tcpctl *, Tcp *, Block **, ushort *); +void udprcvmsg(Ipconv *, Block*); +void update(Ipconv *, Tcp *); #define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -508,8 +497,6 @@ void tcpflushincoming(Ipconv*); #define BLKFRAG(xp) ((Ipfrag *)((xp)->base)) #define PREC(x) ((x)>>5 & 7) -#define WORKBUF 64 - extern Ipaddr Myip[7]; extern Ipaddr Mymask; extern Ipaddr Mynetmask; @@ -528,8 +515,8 @@ extern Queue *Ipoutput; /* offsets into Myip */ enum { - Myself= 0, - Mybcast= 1, - Mynet= 3, - Mysubnet= 5, + Myself = 0, + Mybcast = 1, + Mynet = 3, + Mysubnet = 5, }; diff --git a/port/net.c b/port/net.c index 306dffcb02b0b8574d869f55ffebae23e9d6758c..834eb7f0e697d9f039899d4fc20df427f1187a31 100644 --- a/port/net.c +++ b/port/net.c @@ -65,6 +65,8 @@ netgen(Chan *c, void *vp, int ntab, int i, Dir *dp) q.path = Qclone; devdir(c, q, "clone", 0, eve, 0666, dp); }else if(i <= np->nconv){ + if(findprot(np, i-1) == 0) + return 0; q.path = CHDIR|STREAMQID(i-1, Q3rd); sprint(buf, "%d", i-1); devdir(c, q, buf, 0, eve, 0555, dp); @@ -75,7 +77,9 @@ netgen(Chan *c, void *vp, int ntab, int i, Dir *dp) /* third level depends on the number of info files */ p = findprot(np, STREAMID(c->qid.path)); - if(p && *p->owner){ + if(p == 0) + return 0; + if(*p->owner){ o = p->owner; perm = p->mode; } else { @@ -215,7 +219,6 @@ netopen(Chan *c, int omode, Network *np) if(np->protop && c->stream->devq->next->info != np->protop) pushq(c->stream, np->protop); p = findprot(np, id); -if(p == 0) print("netopen: can't find %d\n", id); if(netown(p, u->p->user, omode&7) < 0) error(Eperm); break; diff --git a/port/page.c b/port/page.c index 489d3dfabeadb13eb07712ebfaaa851f058c08df..50311c84179292935988c51377b16c3e8952573f 100644 --- a/port/page.c +++ b/port/page.c @@ -101,7 +101,7 @@ newpage(int clear, Segment **s, ulong va) palloc.freecount--; unlock(&palloc); - lockpage(p); + lock(p); if(p->ref != 0) panic("newpage"); @@ -112,7 +112,7 @@ newpage(int clear, Segment **s, ulong va) p->modref = 0; for(i = 0; i < MAXMACH; i++) p->cachectl[i] = PG_NOFLUSH; - unlockpage(p); + unlock(p); if(clear){ k = kmap(p); @@ -138,7 +138,7 @@ putpage(Page *p) return; } - lockpage(p); + lock(p); if(--p->ref == 0) { lock(&palloc); if(p->image && p->image != &swapimage) { @@ -169,7 +169,7 @@ putpage(Page *p) palloc.freecount++; /* Release people waiting for memory */ unlock(&palloc); } - unlockpage(p); + unlock(p); } void @@ -177,16 +177,15 @@ simpleputpage(Page *pg) /* Always call with palloc locked */ { pg->ref = 0; palloc.freecount++; - if(palloc.head) { - pg->next = palloc.head; - palloc.head->prev = pg; - pg->prev = 0; - palloc.head = pg; - } - else { + if(palloc.head == 0) { palloc.head = palloc.tail = pg; pg->prev = pg->next = 0; + return; } + pg->next = palloc.head; + palloc.head->prev = pg; + pg->prev = 0; + palloc.head = pg; } void @@ -223,10 +222,10 @@ duppage(Page *p) /* Always call with p locked */ unlock(&palloc); - lockpage(np); /* Cache the new version */ + lock(np); /* Cache the new version */ if(np->ref != 0) { /* Stolen by new page */ uncachepage(p); - unlockpage(np); + unlock(np); return; } @@ -235,7 +234,7 @@ duppage(Page *p) /* Always call with p locked */ np->daddr = p->daddr; copypage(p, np); cachepage(np, p->image); - unlockpage(np); + unlock(np); uncachepage(p); } @@ -256,20 +255,21 @@ uncachepage(Page *p) /* Always called with a locked page */ { Page **l, *f; - if(p->image) { - lock(&palloc.hashlock); - l = &pghash(p); - for(f = *l; f; f = f->hash) { - if(f == p) { - *l = p->hash; - break; - } - l = &f->hash; + if(p->image == 0) + return; + + lock(&palloc.hashlock); + l = &pghash(p); + for(f = *l; f; f = f->hash) { + if(f == p) { + *l = p->hash; + break; } - unlock(&palloc.hashlock); - putimage(p->image); - p->image = 0; + l = &f->hash; } + unlock(&palloc.hashlock); + putimage(p->image); + p->image = 0; } void @@ -296,9 +296,9 @@ lookpage(Image *i, ulong daddr) if(f->image == i && f->daddr == daddr) { unlock(&palloc.hashlock); - lockpage(f); + lock(f); if(f->image != i || f->daddr != daddr) { - unlockpage(f); + unlock(f); return 0; } @@ -317,7 +317,7 @@ lookpage(Image *i, ulong daddr) } unlock(&palloc); - unlockpage(f); + unlock(f); return f; } } @@ -328,8 +328,8 @@ lookpage(Image *i, ulong daddr) Pte* ptecpy(Pte *old) { - Page **src, **dst, **end; Pte *new; + Page **src, **dst, **end; new = ptealloc(); dst = &new->pages[old->first-old->pages]; @@ -339,9 +339,9 @@ ptecpy(Pte *old) if(onswap(*src)) dupswap(*src); else { - lockpage(*src); + lock(*src); (*src)->ref++; - unlockpage(*src); + unlock(*src); } new->last = dst; *dst = *src; @@ -384,32 +384,3 @@ freepte(Segment *s, Pte *p) } free(p); } - -/* Multiplex a hardware lock for per page manipulations */ -void -lockpage(Page *p) -{ - int s; - - for(;;) { - if(p->lock == 0) { - s = splhi(); - lock(&pglock); - if(p->lock == 0) { - p->lock = 1; - unlock(&pglock); - splx(s); - return; - } - unlock(&pglock); - splx(s); - } - sched(); - } -} - -void -unlockpage(Page *p) -{ - p->lock = 0; -} diff --git a/port/pgrp.c b/port/pgrp.c index b5dba70012b76c9f978126bbc62073ecc151633c..08223d431409d24247fd709a0cd45372c0c16ce4 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -114,23 +114,6 @@ closepgrp(Pgrp *p) } } -void -closeegrp(Egrp *eg) -{ - Evalue *e, *next; - - if(decref(eg) == 0) { - for(e = eg->entries; e; e = next) { - next = e->link; - free(e->name); - if(e->value) - free(e->value); - free(e); - } - free(eg); - } -} - void closefgrp(Fgrp *f) { @@ -160,29 +143,6 @@ newmount(Mhead *mh, Chan *to) return m; } -void -envcpy(Egrp *to, Egrp *from) -{ - Evalue **l, *ne, *e; - - l = &to->entries; - qlock(from); - for(e = from->entries; e; e = e->link) { - ne = smalloc(sizeof(Evalue)); - ne->name = smalloc(strlen(e->name)+1); - strcpy(ne->name, e->name); - if(e->value) { - ne->value = smalloc(e->len); - memmove(ne->value, e->value, e->len); - ne->len = e->len; - } - ne->path = ++to->path; - *l = ne; - l = &ne->link; - } - qunlock(from); -} - void pgrpcpy(Pgrp *to, Pgrp *from) { diff --git a/port/portdat.h b/port/portdat.h index 78e26b448f5586d39577ac5289d795f276b7dd57..a741e9b34c9bf067c8119f0c3534e093d7ed7f60 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -32,11 +32,16 @@ typedef struct Queue Queue; typedef struct Ref Ref; typedef struct Rendez Rendez; typedef struct RWlock RWlock; +typedef struct Sargs Sargs; typedef struct Segment Segment; typedef struct Stream Stream; typedef struct Talarm Talarm; typedef struct Waitq Waitq; typedef int Devgen(Chan*, Dirtab*, int, int, Dir*); +typedef void Streamput(Queue*, Block*); +typedef void Streamopen(Queue*, Stream*); +typedef void Streamclose(Queue*); +typedef void Streamreset(void); #include "fcall.h" @@ -80,6 +85,12 @@ struct Alarms Proc *head; }; +#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */ +struct Sargs +{ + ulong args[MAXSYSARG]; +}; + /* Block.flags */ #define S_DELIM 0x80 #define S_CLASS 0x07 @@ -238,11 +249,6 @@ struct KIOQ int count; }; -extern IOQ lineq; -extern IOQ printq; -extern IOQ mouseq; -extern KIOQ kbdq; - struct Mount { ulong mountid; @@ -271,16 +277,18 @@ struct Note int flag; /* whether system posted it */ }; -/* Fields for cache control of pages */ -#define PG_NOFLUSH 0 -#define PG_TXTFLUSH 1 -#define PG_DATFLUSH 2 -/* Simulated modified and referenced bits */ -#define PG_MOD 0x01 -#define PG_REF 0x02 +enum +{ + PG_NOFLUSH = 0, /* Fields for cache control of pages */ + PG_TXTFLUSH = 1, + PG_DATFLUSH = 2, + PG_MOD = 0x01, /* Simulated modified and referenced bits */ + PG_REF = 0x02, +}; struct Page { + Lock; ulong pa; /* Physical address in memory */ ulong va; /* Virtual address for user */ ulong daddr; /* Disc address on swap */ @@ -328,17 +336,19 @@ struct Pte }; /* Segment types */ -#define SG_TYPE 07 /* Mask type of segment */ -#define SG_TEXT 00 -#define SG_DATA 01 -#define SG_BSS 02 -#define SG_STACK 03 -#define SG_SHARED 04 -#define SG_PHYSICAL 05 -#define SG_SHDATA 06 - -/* Segment flags */ -#define SG_RONLY 040 /* Segment is read only */ +enum +{ + SG_TYPE = 07, /* Mask type of segment */ + SG_TEXT = 00, + SG_DATA = 01, + SG_BSS = 02, + SG_STACK = 03, + SG_SHARED = 04, + SG_PHYSICAL = 05, + SG_SHDATA = 06, + + SG_RONLY = 040, /* Segment is read only */ +}; #define PG_ONSWAP 1 #define pagedout(s) (((ulong)s)==0 || (((ulong)s)&PG_ONSWAP)) @@ -464,12 +474,9 @@ enum SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, NSEG }; -/* - * Process states - */ enum { - Dead = 0, + Dead = 0, /* Process states */ Moribund, Ready, Scheding, @@ -479,24 +486,12 @@ enum Broken, Stopped, Rendezvous, -}; -/* - * devproc requests - */ -enum -{ - Proc_stopme = 1, - Proc_exitme = 2, - Proc_traceme = 3, -}; + Proc_stopme = 1, /* devproc requests */ + Proc_exitme, + Proc_traceme, -/* - * Proc.time - */ -enum -{ - TUser, + TUser = 0, /* Proc.time */ TSys, TReal, TCUser, @@ -573,14 +568,14 @@ struct Proc */ struct Qinfo { - void (*iput)(Queue*, Block*); /* input routine */ - void (*oput)(Queue*, Block*); /* output routine */ - void (*open)(Queue*, Stream*); - void (*close)(Queue*); - char *name; - void (*reset)(void); /* initialization */ - char nodelim; /* True if stream does not preserve delimiters */ - Qinfo *next; + Streamput *iput; /* input routine */ + Streamput *oput; /* output routine */ + Streamopen *open; + Streamclose *close; + char *name; + Streamreset *reset; /* initialization */ + char nodelim; /* True if stream does not preserve delimiters */ + Qinfo *next; }; /* @@ -678,30 +673,30 @@ struct Network Netinf info[5]; Netprot *prot; /* linked list of protections */ }; -#define MAJOR(q) ((q) >> 8) -#define MINOR(q) ((q) & 0xff) -#define DEVICE(a,i) (((a)<<8) | (i)) -#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */ #define PRINTSIZE 256 #define NUMSIZE 12 /* size of formatted number */ -extern FPsave initfp; extern Conf conf; -extern ulong initcode[]; +extern char* conffile; +extern int cpuserver; +extern char* devchar; extern Dev devtab[]; -extern char *devchar; -extern char *conffile; -extern char *statename[]; -extern Palloc palloc; -extern Pgrps pgrpalloc; -extern Image swapimage; extern char eve[]; +extern ulong initcode[]; +extern FPsave initfp; +extern KIOQ kbdq; +extern IOQ lineq; +extern IOQ mouseq; +extern Ref noteidalloc; extern int nrdy; +extern IOQ printq; +extern char* statename[]; +extern Image swapimage; extern char sysname[NAMELEN]; -extern int cpuserver; -extern Ref noteidalloc; extern Talarm talarm; +extern Palloc palloc; +extern Pgrps pgrpalloc; #define CHDIR 0x80000000L #define CHAPPEND 0x40000000L @@ -710,8 +705,8 @@ extern Talarm talarm; /* * auth messages */ -#define AUTHLEN 8 -enum{ +enum +{ FScchal = 1, FSschal, FSok, @@ -721,4 +716,6 @@ enum{ RXschal = 0, RXstick = 1, + + AUTHLEN = 8, }; diff --git a/port/portfns.h b/port/portfns.h index 7e2ca623f8bc53c2cacf2ef1f0da42541e874f84..633867afa51f48b2a66b058bbdf37313b8ce3537 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -99,7 +99,6 @@ long latin1(uchar*); void lights(int); void lock(Lock*); void lockinit(void); -void lockpage(Page*); Page* lookpage(Image*, ulong); void machinit(void); void* malloc(ulong); @@ -221,7 +220,7 @@ int streamparse(char*, Block*); long streamread(Chan*, void*, long); void streamstat(Chan*, char*, char*); long streamwrite(Chan*, void*, long, int); -long stringread(void*, long, char*, ulong); +void naildownstream(Stream*); void swapinit(void); long syscall(Ureg*); void tsleep(Rendez*, int (*)(void*), void*, int); @@ -229,7 +228,6 @@ void uncachepage(Page*); long unicode(uchar*); long unionread(Chan*, void*, long); void unlock(Lock*); -void unlockpage(Page*); void unmount(Chan*, Chan*); void urpfillstats(Chan*, char*, int); void userinit(void); diff --git a/port/segment.c b/port/segment.c index 71d2b540a286b6282ec18ce06abb0d872568f778..94515846c3921117036559e1c02eb43324ae0ab7 100644 --- a/port/segment.c +++ b/port/segment.c @@ -15,15 +15,14 @@ void imagereclaim(void); #define IHASHSIZE 64 #define ihash(s) imagealloc.hash[s%IHASHSIZE] -struct Imagealloc +struct { Lock; Image *free; Image *hash[IHASHSIZE]; + QLock ireclaim; }imagealloc; -static QLock ireclaim; - void initseg(void) { @@ -254,29 +253,28 @@ imagereclaim(void) { Page *p; - if(!canqlock(&ireclaim)) /* Somebody is already cleaning the page cache */ + /* Somebody is already cleaning the page cache */ + if(!canqlock(&imagealloc.ireclaim)) return; lock(&palloc); for(p = palloc.head; p; p = p->next) { - if(p->image) - if(p->ref == 0) - if(p->image != &swapimage) { - lockpage(p); + if(p->image && p->ref == 0 && p->image != &swapimage) { + lock(p); if(p->ref == 0) uncachepage(p); - unlockpage(p); + unlock(p); } } unlock(&palloc); - qunlock(&ireclaim); + qunlock(&imagealloc.ireclaim); } void putimage(Image *i) { - Image *f, **l; Chan *c; + Image *f, **l; if(i == &swapimage) return; @@ -301,7 +299,7 @@ putimage(Image *i) imagealloc.free = i; unlock(&imagealloc); - close(c); /* Delay close because we could error */ + close(c); return; } unlock(i); diff --git a/port/stream.c b/port/stream.c index 701ff9a7e16cea4cc5109b1416dbc890c5a7427f..7bc46f843b8a6392e8b636c4ac1c34f0ef093f1e 100644 --- a/port/stream.c +++ b/port/stream.c @@ -275,7 +275,7 @@ copyb(Block *bp, int count) /* * process end line discipline */ -static void stputq(Queue*, Block*); +static Streamput stputq; Qinfo procinfo = { stputq, @@ -626,15 +626,6 @@ static Sthash ht[Nhash]; static void hangup(Stream*); -void -streaminit(void) -{ - /* - * make stream modules available - */ - streaminit0(); -} - /* * A stream device consists of the contents of streamdir plus * any directory supplied by the actual device. @@ -834,6 +825,16 @@ streamexit(Stream *s, int locked) qunlock(hb); } +/* + * nail down a stream so that it can't be closed + */ +void +naildownstream(Stream *s) +{ + s->opens++; + s->inuse++; +} + /* * Decrement the open count. When it goes to zero, call the close * routines for each queue in the stream. @@ -902,7 +903,7 @@ streamclose(Chan *c) void stputq(Queue *q, Block *bp) { - int delim; + int awaken; Stream *s; if(bp->type == M_HANGUP){ @@ -914,7 +915,7 @@ stputq(Queue *q, Block *bp) q->flag |= QHUNGUP; q->other->flag |= QHUNGUP; wakeup(q->other->rp); - delim = 1; + awaken = 1; } else { lock(q); if(q->first) @@ -923,21 +924,21 @@ stputq(Queue *q, Block *bp) q->first = bp; q->len += BLEN(bp); q->nb++; - delim = bp->flags & S_DELIM; + awaken = bp->flags & S_DELIM; while(bp->next) { bp = bp->next; q->len += BLEN(bp); q->nb++; - delim |= bp->flags & S_DELIM; + awaken |= bp->flags & S_DELIM; } q->last = bp; if(q->len >= Streamhi || q->nb >= Streambhi){ q->flag |= QHIWAT; - delim = 1; + awaken = 1; } unlock(q); } - if(delim) + if(awaken) wakeup(q->rp); } @@ -1177,7 +1178,8 @@ streamwrite(Chan *c, void *a, long n, int docopy) Queue *q; long rem; int i; - Block *bp, *first, *last; + Block *bp; + char *va; s = c->stream; @@ -1199,32 +1201,28 @@ streamwrite(Chan *c, void *a, long n, int docopy) } /* - * copy the whole write into kernel space + * Write the message using blocks <= Streamhi bytes longs */ - first = last = 0; - for(rem = n; ; rem -= i) { - bp = allocb(rem); - i = bp->lim - bp->wptr; - if(i >= rem) + va = a; + rem = n; + for(;;){ + if(rem > Streamhi) + i = Streamhi; + else i = rem; - memmove(bp->wptr, a, i); + bp = allocb(i); + memmove(bp->wptr, va, i); bp->wptr += i; - bp->type = M_DATA; - a = ((char*)a) + i; - if(first == 0) - first = bp; - else - last->next = bp; - last = bp; - if(i == rem) + va += i; + rem -= i; + if(rem > 0){ + FLOWCTL(q, bp); + } else { + bp->flags |= S_DELIM; + FLOWCTL(q, bp); break; + } } - - /* - * send it down stream - */ - last->flags |= S_DELIM; - FLOWCTL(q, first); return n; } @@ -1323,8 +1321,3 @@ getfields(char *lp, char **fields, int n, char sep) } return i; } - -void -dumpqueues(void) -{ -} diff --git a/port/swap.c b/port/swap.c index f6a3ec2f6ae1062d27f8eb9ebc398747f00a64de..4c1adbfcc10150c0c00fb3ba0cc1484a5df1fff5 100644 --- a/port/swap.c +++ b/port/swap.c @@ -264,10 +264,10 @@ pagepte(int type, Segment *s, Page **pg) case SG_STACK: case SG_SHARED: case SG_SHDATA: - lockpage(outp); + lock(outp); outp->ref++; uncachepage(outp); - unlockpage(outp); + unlock(outp); daddr = newswap(); outp->daddr = daddr; @@ -314,9 +314,9 @@ executeio(void) poperror(); /* Free up the page after I/O */ - lockpage(out); + lock(out); out->ref--; - unlockpage(out); + unlock(out); putpage(out); } ioptr = 0; diff --git a/power/dat.h b/power/dat.h index 64ac706acde105c6096a2ba60ec1c9240022ae57..8dd7802b0f9f0b1c587337e64a94385c9cd7dded 100644 --- a/power/dat.h +++ b/power/dat.h @@ -51,7 +51,6 @@ struct Conf ulong arp; /* Arp table size */ ulong frag; /* Ip fragment assemble queue size */ ulong cntrlp; /* panic on ^P */ - ulong dkif; /* number of datakit interfaces */ }; /* @@ -185,6 +184,7 @@ struct User char elem[NAMELEN]; /* last name element from namec */ Chan *slash; Chan *dot; + Sargs s; /* * Rest of structure controlled by devproc.c and friends. * qlock(&p->debug) to modify. diff --git a/power/main.c b/power/main.c index 6f252040d0a53b39d811b994721575d9ca97dc4d..cb9c5b97b56855d35f0b78ce0e6ec17697e73cb7 100644 --- a/power/main.c +++ b/power/main.c @@ -222,8 +222,10 @@ userinit(void) p = newproc(); p->pgrp = newpgrp(); - p->egrp = newegrp(); - p->fgrp = newfgrp(); + p->egrp = smalloc(sizeof(Egrp)); + p->egrp->ref = 1; + p->fgrp = smalloc(sizeof(Fgrp)); + p->fgrp->ref = 1; p->procmode = 0640; strcpy(p->text, "*init*"); @@ -537,7 +539,6 @@ confinit(void) conf.nproc = 100; conf.nswap = 262144; conf.nimage = 200; - conf.dkif = 1; conf.ipif = 8; conf.ip = 64; conf.arp = 32; diff --git a/power/trap.c b/power/trap.c index 7b8a7c5bc13775eca3a5cad16eed71b70ce50b46..6c8c899914871548fca108838646bce94da59d85 100644 --- a/power/trap.c +++ b/power/trap.c @@ -497,7 +497,6 @@ syscall(Ureg *aur) ulong sp; ulong r1; Ureg *ur; - char *msg; Proc *p; m->syscall++; @@ -524,22 +523,25 @@ syscall(Ureg *aur) u->nerrlab = 0; ret = -1; if(!waserror()){ - if(r1 >= sizeof systab/sizeof systab[0]){ - pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc); - msg = "sys: bad sys call"; - Bad: - postnote(p, 1, msg, NDebug); + if(r1 >= sizeof systab/sizeof systab[0]) { + pprint("bad sys call number %d pc %lux\n", r1, ur->pc); + postnote(p, 1, "sys: bad sys call", NDebug); error(Ebadarg); } + if(sp & (BY2WD-1)){ - pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - msg = "sys: odd stack"; - goto Bad; + pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp); + postnote(p, 1, "sys: odd stack", NDebug); + error(Ebadarg); } - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) - validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); + + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) + validaddr(sp, sizeof(Sargs), 0); + + u->s = *((Sargs*)(sp+BY2WD)); p->psstate = sysctab[r1]; - ret = (*systab[r1])((ulong*)(sp+BY2WD)); + + ret = (*systab[r1])(u->s.args); } ur->pc += 4; u->nerrlab = 0; diff --git a/ss/dat.h b/ss/dat.h index ad2d9ad7db4ac273198c2619a5509543b41546a4..402af215bc982abd1d44614e9aa835ec6dc05320 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -67,15 +67,12 @@ struct Conf ulong nimage; /* number of page cache image headers */ ulong nswap; /* number of swap blocks */ ulong upages; /* number of user pages */ - int nurp; /* max urp conversations */ - int nasync; /* number of async protocol modules */ int copymode; /* 0 is copy on write, 1 is copy on reference */ ulong ipif; /* Ip protocol interfaces */ ulong ip; /* Ip conversations per interface */ ulong arp; /* Arp table size */ ulong frag; /* Ip fragment assemble queue size */ int cntrlp; /* panic on ^P */ - int dkif; /* number of datakit interfaces */ }; /* @@ -140,6 +137,7 @@ struct User char elem[NAMELEN]; /* last name element from namec */ Chan *slash; Chan *dot; + Sargs s; /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/ss/main.c b/ss/main.c index d494fc71549dc9724fd3268c0f4c59e91f2848e8..aaf9e3f4c613ce41b8791144f4b466feb11b0e46 100644 --- a/ss/main.c +++ b/ss/main.c @@ -218,7 +218,6 @@ confinit(void) conf.arp = 32; conf.frag = 32; conf.cntrlp = 0; - conf.dkif = 1; } /* diff --git a/ss/trap.c b/ss/trap.c index d18c596aee509ceec3bc69b2b06e1d8b27676130..0ee0e63571cee173d15577dae0f16e54c371efa0 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -351,7 +351,6 @@ syscall(Ureg *aur) ulong sp; ulong r7; Ureg *ur; - char *msg; ur = aur; if(ur->psr & PSRPSUPER) @@ -377,20 +376,23 @@ syscall(Ureg *aur) if(!waserror()){ if(r7 >= sizeof systab/BY2WD){ pprint("bad sys call number %d pc %lux\n", r7, ur->pc); - msg = "sys: bad sys call"; - postnote(u->p, 1, msg, NDebug); + postnote(u->p, 1, "sys: bad sys call", NDebug); error(Ebadarg); } + if(sp & (BY2WD-1)){ pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp); - msg = "sys: odd stack"; - postnote(u->p, 1, msg, NDebug); + postnote(u->p, 1, "sys: odd stack", NDebug); error(Ebadarg); } - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) - validaddr(sp, ((1+MAXSYSARG)*BY2WD), 0); + + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) + validaddr(sp, sizeof(Sargs), 0); + + u->s = *((Sargs*)(sp+1*BY2WD)); u->p->psstate = sysctab[r7]; - ret = (*systab[r7])((ulong*)(sp+1*BY2WD)); + + ret = (*systab[r7])(u->s.args); poperror(); }