code: mafs

Download patch

ref: 9073565b4482a85a72d82508adb76496975734d6
parent: 72614a53c48950b8100c4fbe5b693fac53e912e5
author: 9ferno <gophone2015@gmail.com>
date: Sun Oct 23 07:54:27 EDT 2022

stopped searching through the whole linked list to find an Iobuf to steal

try to use the oldest Iobuf and if that is not good enough, use a new Iobuf.

--- a/iobuf.c
+++ b/iobuf.c
@@ -31,6 +31,21 @@
 	return p;
 }
 
+Iobuf *
+changelru(Iobuf *lru, Iobuf *p)
+{
+	/* remove p from its current position in the lru circular buffer */
+	p->back->fore = p->fore;
+	p->fore->back = p->back;
+
+	/* make p the hb->link and put it at the back of existing link */
+	p->fore = lru;
+	p->back = lru->back;
+	lru->back = p;
+	p->back->fore = p;
+	return p;
+}
+
 /*
 	Get the Iobuf of the disk block at addr from the buffer cache
 	for my use.
@@ -51,7 +66,7 @@
 getbuf(u64 blkno, u8 readonly, u8 freshalloc)
 {
 	Hiob *hp;
-	Iobuf *s, *p;
+	Iobuf *s, *p, *steal;
 	s8 ncollisions;
 
 	hp = &hiob[blkno%nbuckets];
@@ -61,6 +76,7 @@
 				" hiob 0x%p hp 0x%p readonly %d\n",
 			blkno, blkno%nbuckets, getcallerpc(&blkno),
 			hiob, hp, readonly);
+	steal = nil;
 	qlock(hp);
 	s = hp->link;
 	if(s == nil)
@@ -69,16 +85,7 @@
 		ncollisions++;
 		if(p->blkno == blkno){
 			if(p != s){
-				/* remove p from its current position in the lru circular buffer */
-				p->back->fore = p->fore;
-				p->fore->back = p->back;
-
-				/* make p the hb->link and put it at the back of existing link */
-				p->fore = s;
-				p->back = s->back;
-				s->back = p;
-				p->back->fore = p;
-				hp->link = p;
+				hp->link = changelru(s, p);
 			}
 			incref(p);
 			qunlock(hp);
@@ -98,6 +105,9 @@
 			decref(p);
 			return p;
 		}
+		if(p->readers == 0 && p->writer == 0 &&
+			p->ref == 0 && p->dirties == 0)
+			steal = p;
 		p = p->fore;
 		if(p == s)
 			break;
@@ -104,26 +114,24 @@
 	}
 
 	/* maxed out our allowed number of collisions,
-		try to steal an older Iobuf without any ref's.
+		try to steal the oldest Iobuf without any ref's.
 		Ncollisions is a soft limit.
 	 */
-	if(ncollisions >= Ncollisions){
-Another:
-		do{
-			p = s->back;
-			if(p->ref == 0 && p->dirties == 0 && canwlock(p)){
-				if(p->dirties > 0){
-					wunlock(p);
-					goto Another;
-				}
-				hp->link = p;
-				if(chatty9p > 4)
-					dprint("	stealing iobuf 0x%p for blkno %llud\n",
-							p, blkno);
-				goto found;	/* p is wlock() */
-			}
-			s = p;
-		}while(p != hp->link);
+	if(ncollisions >= Ncollisions &&
+		steal != nil && canwlock(steal)){
+		if(steal->readers == 0 && steal->writer == 0 &&
+			steal->ref == 0 && steal->dirties == 0){
+			hp->link = p = changelru(s, steal);
+			if(chatty9p > 4)
+				dprint("	stealing iobuf 0x%p for blkno %llud\n",
+						p, blkno);
+			goto found;	/* p is wlock() */
+		} else
+			/* cannot use steal, just use a new buffer
+				instead of seearching through the linked list
+				to find another unused Iobuf.
+			 */
+			wunlock(steal);
 	}
 
 	/* no unlocked blocks available; add a new one */