~kris/9p

9hist

cc5f512f51cb05b4b4d9125887d4c2137612e776 — David du Colombier 27 years ago edd4dbf
Plan 9 from Bell Labs 1999-01-10
7 files changed, 64 insertions(+), 69 deletions(-)

M port/devcons.c
M port/fault.c
M port/portdat.h
M port/portfns.h
M port/proc.c
M port/qlock.c
M port/swap.c
M port/devcons.c => port/devcons.c +1 -0
@@ 233,6 233,7 @@ echo(Rune r, char *buf, int n)
			xsummary();
			ixsummary();
			poolsummary();
			pagersummary();
			break;
		case 'd':
			if(consdebug != nil)

M port/fault.c => port/fault.c +39 -52
@@ 95,13 95,9 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
		lkp = *pg;
		lock(lkp);

		/* uncache the current swap image (since we may be changing it) */
		if(lkp->image){
			if(lkp->image == &swapimage)
				uncachepage(lkp);
			else
				duppage(lkp);
		}
		/* save a copy of the original for the image cache */
		if(lkp->image)
			duppage(lkp);

		unlock(lkp);
		goto done;


@@ 153,16 149,9 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
			putpage(lkp);
		}
		else {
			/* 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){
				if(lkp->image == &swapimage)
					uncachepage(lkp);
				else
					duppage(lkp);
			}
			/* save a copy of the original for the image cache */
			if(lkp->image)
				duppage(lkp);

			unlock(lkp);
		}


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


@@ 208,22 197,26 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
	ulong daddr;
	Page *loadrec;

retry:
	loadrec = *p;
	if(loadrec == 0) {	/* from a text/data image */
		daddr = s->fstart+soff;
		new = lookpage(s->image, daddr);
		if(new != nil) {
			*p = new;
			return;
		}
	}
	else {			/* from a swap image */
		daddr = swapaddr(loadrec);
		new = lookpage(&swapimage, daddr);
		if(new != nil)
		if(new != nil) {
			putswap(loadrec);
			*p = new;
			return;
		}
	}

	if(new != nil) {			/* Page found from cache */
		*p = new;
		return;
	}

	qunlock(&s->lk);



@@ 254,7 247,11 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
		poperror();
		kunmap(k);
		qlock(&s->lk);
		/* race, we may have multiple simultaneous reads */

		/*
		 *  race, another proc may have gotten here first while
		 *  s->lk was unlocked
		 */
		if(*p == 0) { 
			new->daddr = daddr;
			cachepage(new, s->image);


@@ 265,35 262,9 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
	}
	else {				/* This is paged out */
		c = swapimage.c;
		qlock(&swapimage.rdlock);	/* mutex */

		/*
		 *  multiple processes could be swapping in the
		 *  same page for the same segment
		 */
		if(!pagedout(*p)){
			putpage(new);
			qunlock(&swapimage.rdlock);
			goto done;
		}

		/*
		 *  multiple processes could be swapping in the
		 *  same page for different segments
		 */
		new2 = lookpage(&swapimage, daddr);
		if(new2 != nil){
			putpage(new);
			*p = new2;
			putswap(loadrec);
			qunlock(&swapimage.rdlock);
			goto done;
		}

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


@@ 307,12 278,28 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
		kunmap(k);
		qlock(&s->lk);

		/*
		 *  race, another proc may have gotten here first
		 *  (and the pager may have run on that page) while
		 *  s->lk was unlocked
		 */
		if(*p != loadrec){
			if(!pagedout(*p)){
				/* another process did it for me */
				putpage(new);
				goto done;
			} else {
print("!");
				/* another process and the pager got in */
				putpage(new);
				goto retry;
			}
		}

		new->daddr = daddr;
		cachepage(new, &swapimage);
		*p = new;
		putswap(loadrec);

		qunlock(&swapimage.rdlock);
	}

done:

M port/portdat.h => port/portdat.h +1 -1
@@ 326,7 326,6 @@ 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


@@ 622,6 621,7 @@ struct Proc
	int	preempted;	/* true if this process hasn't finished the interrupt
				 *  that last preempted it
				 */
	ulong	qpc;		/* pc calling last blocking qlock */

	void	*ureg;		/* User registers for notes */
	void	*dbgreg;	/* User registers for devproc */

M port/portfns.h => port/portfns.h +1 -0
@@ 174,6 174,7 @@ Block*		packblock(Block*);
Block*		padblock(Block*, int);
void		pagechainhead(Page*);
void		pageinit(void);
void		pagersummary(void);
void		panic(char*, ...);
int		parseether(uchar*, char*);
int		parsefields(char*, char**, int, char*);

M port/proc.c => port/proc.c +2 -2
@@ 903,9 903,9 @@ dumpaproc(Proc *p)
	s = p->psstate;
	if(s == 0)
		s = "kproc";
	print("%3lud:%10s pc %8lux dbgpc %8lux  %8s (%s) ut %ld st %ld bss %lux pri %lud\n",
	print("%3lud:%10s pc %8lux dbgpc %8lux  %8s (%s) ut %ld st %ld bss %lux qpc %lux\n",
		p->pid, p->text, p->pc, dbgpc(p),  s, statename[p->state],
		p->time[0], p->time[1], bss, p->priority);
		p->time[0], p->time[1], bss, p->qpc);
}

void

M port/qlock.c => port/qlock.c +1 -0
@@ 35,6 35,7 @@ rwstats.qlockq++;
	q->tail = mp;
	mp->qnext = 0;
	mp->state = Queueing;
	up->qpc = getcallerpc(q);
	unlock(&q->use);
	sched();
}

M port/swap.c => port/swap.c +19 -14
@@ 124,7 124,9 @@ loop:
			if(p->state == Dead || p->kp)
				continue;

			qlock(&p->seglock);
			if(!canqlock(&p->seglock))
				continue;		/* process changing its segments */

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


@@ 278,19 280,6 @@ pagepte(int type, Page **pg)
	case SG_SHARED:
	case SG_SHDATA:
	case SG_MAP:
		/* if it's already on disk, no need to do io again */
#ifdef asdf
		lock(outp);
		if(outp->image == &swapimage){
			dupswap((Page*)outp->daddr);
			*pg = (Page*)(outp->daddr|PG_ONSWAP);
			unlock(outp);
			putpage(outp);
			return;
		}
		unlock(outp);
#endif asdf

		/*
		 *  get a new swap address and clear any pages
		 *  referring to it from the cache


@@ 312,6 301,7 @@ pagepte(int type, Page **pg)
		/*
		 *  enter it into the cache so that a fault happening
		 *  during the write will grab the page from the cache
		 *  rather than one partially written to the disk
		 */
		outp->daddr = daddr;
		cachepage(outp, &swapimage);


@@ 324,6 314,15 @@ pagepte(int type, Page **pg)
	}
}

void
pagersummary(void)
{
	print("%lud/%lud memory %lud/%lud swap %d iolist\n",
		palloc.user-palloc.freecount,
		palloc.user, conf.nswap-swapalloc.free, conf.nswap,
		ioptr);
}

static void
executeio(void)
{


@@ 336,13 335,17 @@ executeio(void)
	c = swapimage.c;

	for(i = 0; i < ioptr; i++) {
		if(ioptr > conf.nswppo)
			panic("executeio: ioptr %d > %d\n", ioptr, conf.nswppo);
		out = iolist[i];
		up->psstate = "I/Okm";
		k = kmap(out);
		kaddr = (char*)VA(k);

		if(waserror())
			panic("executeio: page out I/O error");

		up->psstate = "I/Owr";
		n = devtab[c->type]->write(c, kaddr, BY2PG, out->daddr);
		if(n != BY2PG)
			nexterror();


@@ 351,9 354,11 @@ executeio(void)
		poperror();

		/* Free up the page after I/O */
		up->psstate = "I/Odec";
		lock(out);
		out->ref--;
		unlock(out);
		up->psstate = "I/Oput";
		putpage(out);
	}
	ioptr = 0;