git: 9front

Download patch

ref: 45ce81ee957f23e6c28cd0f4c2e17de5a88cf11e
parent: 78217e9990d8786c981a4f0e8b6154bee40d5538
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Mar 16 01:23:38 EDT 2015

kernel: avoid repeated calls to reclaim(), dont miss last page in Pte

when we are skipping a process because we could not acquire
its segment lock, dont call reclaim() again (which is pointless
as we didnt pageout any pages), instead try the next process.

the Pte.last pointer is inclusive, so don't miss the last page
in pageout().

--- a/sys/src/9/port/swap.c
+++ b/sys/src/9/port/swap.c
@@ -7,7 +7,6 @@
 
 static int	canflush(Proc*, Segment*);
 static void	executeio(void);
-static int	needpages(void*);
 static void	pageout(Proc*, Segment*);
 static void	pagepte(int, Page**);
 static void	pager(void*);
@@ -166,6 +165,7 @@
 		}
 
 		if(swapimage.c == nil || swapalloc.free == 0){
+		Killbig:
 			killbig("out of memory");
 			freebroken();		/* can use the memory */
 			sched();
@@ -172,18 +172,14 @@
 			continue;
 		}
 
-		p++;
-		if(p >= ep){
-			p = proctab(0);
-			ageclock++;
-		}
-
-		if(p->state == Dead || p->noswap)
-			continue;
-
-		if(!canqlock(&p->seglock))
-			continue;		/* process changing its segments */
-
+		i = ageclock;
+		do {
+			if(++p >= ep){
+				if(++ageclock == i)
+					goto Killbig;
+				p = proctab(0);
+			}
+		} while(p->state == Dead || p->noswap || !canqlock(&p->seglock));
 		up->psstate = "Pageout";
 		for(i = 0; i < NSEG; i++) {
 			if((s = p->seg[i]) != nil) {
@@ -239,9 +235,9 @@
 	size = s->mapsize;
 	for(i = 0; i < size; i++) {
 		l = s->map[i];
-		if(l == 0)
+		if(l == nil)
 			continue;
-		for(pg = l->first; pg < l->last; pg++) {
+		for(pg = l->first; pg <= l->last; pg++) {
 			entry = *pg;
 			if(pagedout(entry))
 				continue;
@@ -389,7 +385,7 @@
 	ioptr = 0;
 }
 
-static int
+int
 needpages(void*)
 {
 	return palloc.freecount < swapalloc.headroom;
--