shithub: riscv

Download patch

ref: ea5a23d39a5a5313144055481e85689809d65673
parent: 27830ae53e8dfaea0c809410f27c66214c6d2560
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Wed Dec 21 21:17:29 EST 2011

kernel: make mntcache effective, be carefull

--- a/sys/src/9/port/cache.c
+++ b/sys/src/9/port/cache.c
@@ -113,10 +113,8 @@
 		panic("cinit: no memory");
 
 	/* a better algorithm would be nice */
-//	if(conf.npage*BY2PG > 200*MB)
-//		maxcache = 10*MAXCACHE;
-//	if(conf.npage*BY2PG > 400*MB)
-//		maxcache = 50*MAXCACHE;
+	if(conf.npage*BY2PG > 200*MB)
+		maxcache = 10*MAXCACHE;
 
 	for(i = 0; i < NFILE-1; i++) {
 		m->next = m+1;
@@ -171,17 +169,16 @@
 void
 cnodata(Mntcache *m)
 {
-	Extent *e, *n;
+	Extent *e;
 
 	/*
 	 * Invalidate all extent data
 	 * Image lru will waste the pages
 	 */
-	for(e = m->list; e; e = n) {
-		n = e->next;
+	while(e = m->list){
+		m->list = e->next;
 		extentfree(e);
 	}
-	m->list = 0;
 }
 
 void
@@ -215,13 +212,11 @@
 copen(Chan *c)
 {
 	int h;
-	Extent *e, *next;
 	Mntcache *m, *f, **l;
 
 	/* directories aren't cacheable and append-only files confuse us */
 	if(c->qid.type&(QTDIR|QTAPPEND))
 		return;
-
 	h = c->qid.path%NHASH;
 	lock(&cache);
 	for(m = cache.hash[h]; m; m = m->hash) {
@@ -228,17 +223,16 @@
 		if(m->qid.path == c->qid.path)
 		if(m->qid.type == c->qid.type)
 		if(m->dev == c->dev && m->type == c->type) {
-			c->mcp = m;
-			ctail(m);
-			unlock(&cache);
-
 			/* File was updated, invalidate cache */
-			if(m->qid.vers != c->qid.vers) {
+			if(m->qid.vers != c->qid.vers){
+				if(!canqlock(m))
+					goto Busy;
 				m->qid.vers = c->qid.vers;
-				qlock(m);
-				cnodata(m);
-				qunlock(m);
+				goto Update;
 			}
+			ctail(m);
+			c->mcp = m;
+			unlock(&cache);
 			return;
 		}
 	}
@@ -245,6 +239,8 @@
 
 	/* LRU the cache headers */
 	m = cache.head;
+	if(!canqlock(m))
+		goto Busy;
 	l = &cache.hash[m->qid.path%NHASH];
 	for(f = *l; f; f = f->hash) {
 		if(f == m) {
@@ -261,20 +257,16 @@
 	l = &cache.hash[h];
 	m->hash = *l;
 	*l = m;
+Update:
 	ctail(m);
-
-	qlock(m);
 	c->mcp = m;
-	e = m->list;
-	m->list = 0;
 	unlock(&cache);
-
-	while(e) {
-		next = e->next;
-		extentfree(e);
-		e = next;
-	}
+	cnodata(m);
 	qunlock(m);
+	return;
+Busy:
+	unlock(&cache);
+	c->mcp = 0;
 }
 
 static int
@@ -313,6 +305,7 @@
 	qlock(m);
 	if(cdev(m, c) == 0) {
 		qunlock(m);
+		c->mcp = 0;
 		return 0;
 	}
 
@@ -483,6 +476,7 @@
 	qlock(m);
 	if(cdev(m, c) == 0) {
 		qunlock(m);
+		c->mcp = 0;
 		return;
 	}
 
@@ -541,7 +535,9 @@
 			len -= o;
 			offset += o;
 			if(len <= 0) {
-if(f && p->start + p->len > f->start) print("CACHE: p->start=%uld p->len=%d f->start=%uld\n", p->start, p->len, f->start);
+				if(f && p->start + p->len > f->start)
+					print("CACHE: p->start=%uld p->len=%d f->start=%uld\n",
+						p->start, p->len, f->start);
 				qunlock(m);
 				return;
 			}
@@ -575,6 +571,7 @@
 	qlock(m);
 	if(cdev(m, c) == 0) {
 		qunlock(m);
+		c->mcp = 0;
 		return;
 	}
 
--- a/sys/src/9/port/chan.c
+++ b/sys/src/9/port/chan.c
@@ -1488,9 +1488,6 @@
 			/* save registers else error() in open has wrong value of c saved */
 			saveregisters();
 
-			if(omode == OEXEC)
-				c->flag &= ~CCACHE;
-
 			c = devtab[c->type]->open(c, omode&~OCEXEC);
 
 			if(omode & OCEXEC)
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -409,6 +409,7 @@
 		 * Therefore set type to 0 for now; rootclose is known to be safe.
 		 */
 		nc->type = 0;
+		nc->flag |= (c->flag & CCACHE);
 		alloc = 1;
 	}
 	wq->clone = nc;
--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -200,7 +200,7 @@
 	Page *new;
 	KMap *k;
 	Chan *c;
-	int n, ask;
+	int n, ask, cache;
 	char *kaddr;
 	ulong daddr;
 	Page *loadrec;
@@ -238,7 +238,9 @@
 	k = kmap(new);
 	kaddr = (char*)VA(k);
 
+	cache = c->flag & CCACHE;
 	while(waserror()) {
+		c->flag |= cache;
 		if(strcmp(up->errstr, Eintr) == 0)
 			continue;
 		kunmap(k);
@@ -245,8 +247,9 @@
 		putpage(new);
 		faulterror(Eioload, c, 0);
 	}
-
+	c->flag &= ~CCACHE;
 	n = devtab[c->type]->read(c, kaddr, ask, daddr);
+	c->flag |= cache;
 	if(n != ask)
 		faulterror(Eioload, c, 0);
 	if(ask < BY2PG)