~kris/9p

9hist

a7cce8b741b0870b12232bc993b6733b17df3e64 — David du Colombier 27 years ago c4f34b8
Plan 9 from Bell Labs 1999-01-08
8 files changed, 110 insertions(+), 23 deletions(-)

M port/devproc.c
M port/fault.c
M port/page.c
M port/portdat.h
M port/portfns.h
M port/proc.c
M port/swap.c
M port/sysproc.c
M port/devproc.c => port/devproc.c +2 -0
@@ 975,6 975,7 @@ txt2data(Proc *p, Segment *s)
	ps->flen = s->flen;
	ps->flushme = 1;

	qlock(&p->seglock);
	for(i = 0; i < NSEG; i++)
		if(p->seg[i] == s)
			break;


@@ 985,6 986,7 @@ txt2data(Proc *p, Segment *s)
	putseg(s);
	qlock(&ps->lk);
	p->seg[i] = ps;
	qunlock(&p->seglock);

	return ps;
}

M port/fault.c => port/fault.c +34 -13
@@ 51,6 51,7 @@ int
fixfault(Segment *s, ulong addr, int read, int doputmmu)
{
	int type;
	int ref;
	Pte **p, *etp;
	char buf[ERRLEN];
	ulong va, mmuphys=0, soff;


@@ 92,6 93,11 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)

		lkp = *pg;
		lock(lkp);

		/* uncache the current page (since we may be changing it)
		 * and, if a text page, put a duplicate back onto
		 * the free list
		 */
		if(lkp->image)
			duppage(lkp);
		unlock(lkp);


@@ 129,7 135,11 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)

		lkp = *pg;
		lock(lkp);
		if(lkp->ref > 1) {
		if(lkp->image == &swapimage && lkp->daddr)
			ref = lkp->ref + swapcount(lkp->daddr);
		else
			ref = lkp->ref;
		if(ref > 1) {
			unlock(lkp);
			new = newpage(0, &s, addr);
			if(s == 0)


@@ 139,7 149,8 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
			putpage(lkp);
		}
		else {
			/* put a duplicate of a text page back onto
			/* uncache the current page (since we may be changing it)
			 * and, if a text page, put a duplicate back onto
			 * the free list
			 */
			if(lkp->image)


@@ 181,7 192,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
void
pio(Segment *s, ulong addr, ulong soff, Page **p)
{
	Page *new;
	Page *new, *new2;
	KMap *k;
	Chan *c;
	int n, ask;


@@ 197,7 208,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
	else {
		daddr = swapaddr(loadrec);
		new = lookpage(&swapimage, daddr);
		if(new)
		if(new != nil)
			putswap(loadrec);
	}



@@ 235,7 246,8 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
		poperror();
		kunmap(k);
		qlock(&s->lk);
		if(*p == 0) { 		/* Someone may have got there first */
		/* race, we may have multiple simultaneous reads */
		if(*p == 0) { 
			new->daddr = daddr;
			cachepage(new, s->image);
			*p = new;


@@ 245,10 257,21 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
	}
	else {				/* This is paged out */
		c = swapimage.c;
		qlock(&swapimage.rdlock);	/* mutex */

		new2 = lookpage(&swapimage, daddr);
		if(new2 != nil){
			putpage(new);
			putswap(*p);
			*p = new2;
			qunlock(&swapimage.rdlock);
			return;
		}

		if(waserror()) {
			kunmap(k);
			putpage(new);
			qunlock(&swapimage.rdlock);
			qlock(&s->lk);
			qunlock(&s->lk);
			faulterror("sys: page in I/O error");


@@ 262,14 285,12 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
		kunmap(k);
		qlock(&s->lk);

		if(pagedout(*p)) {
			new->daddr = daddr;
			cachepage(new, &swapimage);
			putswap(*p);
			*p = new;
		}
		else
			putpage(new);
		new->daddr = daddr;
		putswap(*p);
		cachepage(new, &swapimage);
		*p = new;

		qunlock(&swapimage.rdlock);
	}

	if(s->flushme)

M port/page.c => port/page.c +11 -2
@@ 270,10 270,16 @@ retry:
	if(retries++ > 10000)
		panic("duppage %d", retries);

	/* No dup for swap/cache pages */
	if(p->ref == 0 || p->image == nil || p->image->notext)
	/* don't dup pages with no image */
	if(p->ref == 0 || p->image == nil)
		return;

	/* No dup for swap/cache pages but we still have to uncache */
	if(p->image->notext){
		uncachepage(p);
		return;
	}

	/*
	 *  normal lock ordering is to call
	 *  lock(&palloc) before lock(p).


@@ 390,6 396,9 @@ cachedel(Image *i, ulong daddr)
	for(f = *l; f; f = f->hash) {
		if(f->image == i && f->daddr == daddr) {
			*l = f->hash;
			putimage(f->image);
			f->image = 0;
			f->daddr = 0;
			break;
		}
		l = &f->hash;

M port/portdat.h => port/portdat.h +2 -0
@@ 326,6 326,7 @@ struct Image
	Image	*hash;			/* Qid hash chains */
	Image	*next;			/* Free list */
	int	notext;			/* no file associated */
	QLock	rdlock;			/* mutex for reading from image */
};

struct Pte


@@ 543,6 544,7 @@ struct Proc
	int	state;
	char	*psstate;	/* What /proc/#/status reports */
	Segment	*seg[NSEG];
	QLock	seglock;	/* locked whenever seg[] changes */
	ulong	pid;
	ulong	noteid;		/* Equivalent of note group */


M port/portfns.h => port/portfns.h +1 -0
@@ 293,6 293,7 @@ int		spllo(void);
void		splx(int);
void		splxpc(int);
void		srvrecover(Chan*, Chan*);
int		swapcount(ulong);
void		swapinit(void);
Block*		trimblock(Block*, int, int);
void		tsleep(Rendez*, int (*)(void*), void*, int);

M port/proc.c => port/proc.c +2 -0
@@ 796,6 796,7 @@ pexit(char *exitstr, int freemem)
	if(!freemem)
		addbroken(up);

	qlock(&up->seglock);
	es = &up->seg[NSEG];
	for(s = up->seg; s < es; s++) {
		if(*s) {


@@ 803,6 804,7 @@ pexit(char *exitstr, int freemem)
			*s = 0;
		}
	}
	qunlock(&up->seglock);

	lock(&up->exl);		/* Prevent my children from leaving waits */
	up->pid = 0;

M port/swap.c => port/swap.c +36 -8
@@ 60,6 60,8 @@ putswap(Page *p)
	lock(&swapalloc);
	idx = &swapalloc.swmap[((ulong)p)/BY2PG];
	if(--(*idx) == 0) {
		if(swapalloc.swmap[((ulong)p)/BY2PG]==255)
			panic("putswap");
		swapalloc.free++;
		if(idx < swapalloc.last)
			swapalloc.last = idx;


@@ 71,10 73,18 @@ void
dupswap(Page *p)
{
	lock(&swapalloc);
	if(swapalloc.swmap[((ulong)p)/BY2PG]==255)
		panic("dupswap");
	swapalloc.swmap[((ulong)p)/BY2PG]++;
	unlock(&swapalloc);
}

int
swapcount(ulong daddr)
{
	return swapalloc.swmap[daddr/BY2PG];
}

void
kickpager(void)
{


@@ 106,17 116,21 @@ loop:
	sleep(&swapalloc.r, needpages, 0);

	while(needpages(junk)) {
		p++;
		if(p >= ep)
			p = proctab(0);

		if(p->state == Dead || p->kp)
			continue;

		if(swapimage.c) {
			p++;
			if(p >= ep)
				p = proctab(0);
	
			if(p->state == Dead || p->kp)
				continue;

			qlock(&p->seglock);
			for(i = 0; i < NSEG; i++) {
				if(!needpages(junk))
				if(!needpages(junk)){
					qunlock(&p->seglock);
					goto loop;
				}

				if(s = p->seg[i]) {
					switch(s->type&SG_TYPE) {


@@ 141,6 155,7 @@ loop:
					}
				}
			}
			qunlock(&p->seglock);
		}
		else {
			if(!cpuserver)


@@ 264,12 279,24 @@ pagepte(int type, Page **pg)
	case SG_SHARED:
	case SG_SHDATA:
	case SG_MAP:
		/* if it's already on disk, we're done */
#ifdef asdf
		lock(outp);
		if(outp->daddr != 0 && outp->image == &swapimage){
			dupswap((Page*)outp->daddr);
			*pg = (Page*)(outp->daddr|PG_ONSWAP);
			unlock(outp);
			putpage(outp);
			return;
		}
		unlock(outp);
#endif asdf

		daddr = newswap();
		cachedel(&swapimage, daddr);
		lock(outp);
		outp->ref++;
		uncachepage(outp);
		unlock(outp);

		/* Enter swap page into cache before segment is unlocked so that
		 * a fault will cause a cache recovery rather than a pagein on a


@@ 278,6 305,7 @@ pagepte(int type, Page **pg)
		outp->daddr = daddr;
		cachepage(outp, &swapimage);
		*pg = (Page*)(daddr|PG_ONSWAP);
		unlock(outp);

		/* Add me to IO transaction list */
		iolist[ioptr++] = outp;

M port/sysproc.c => port/sysproc.c +22 -0
@@ 92,9 92,16 @@ sysrfork(ulong *arg)

	/* Make a new set of memory segments */
	n = flag & RFMEM;
	qlock(&p->seglock);
	if(waserror()){
		qunlock(&p->seglock);
		nexterror();
	}
	for(i = 0; i < NSEG; i++)
		if(up->seg[i])
			p->seg[i] = dupseg(up->seg, i, n);
	qunlock(&p->seglock);
	poperror();

	/* File descriptors */
	if(flag & (RFFDG|RFCFDG)) {


@@ 304,6 311,11 @@ sysexec(ulong *arg)
	if(spage > TSTKSIZ)
		error(Enovmem);

	qlock(&up->seglock);
	if(waserror()){
		qunlock(&up->seglock);
		nexterror();
	}
	up->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG);

	/*


@@ 383,6 395,8 @@ sysexec(ulong *arg)
	s = up->seg[ESEG];
	up->seg[ESEG] = 0;
	up->seg[SSEG] = s;
	qunlock(&up->seglock);
	poperror();
	s->base = USTKTOP-USTKSIZE;
	s->top = USTKTOP;
	relocateseg(s, USTKTOP-TSTKTOP);


@@ 587,6 601,12 @@ syssegdetach(ulong *arg)
	ulong addr;
	Segment *s;

	qlock(&up->seglock);
	if(waserror()){
		qunlock(&up->seglock);
		nexterror();
	}

	s = 0;
	addr = arg[0];
	for(i = 0; i < NSEG; i++)


@@ 609,6 629,8 @@ found:
	up->seg[i] = 0;
	qunlock(&s->lk);
	putseg(s);
	qunlock(&up->seglock);
	poperror();

	/* Ensure we flush any entries from the lost segment */
	flushmmu();