git: 9front

Download patch

ref: fd8f946181181afcff53d8fdf200414bc9a935be
parent: f6303a73c4dba72272e65c4ab0bfdc98fcd3380b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jul 13 08:39:08 EDT 2025

kernel: avoid pagereclaim() on active images when possible

We should not attempt to pagereclaim() active images
while there are still idle ones around.

So do two passes over the image array, and only when
that is exhausted we squeeze active images (which mostly
just yields pages that have been copied-on write
and are now unused from data segment).

--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -450,20 +450,38 @@
 ulong
 imagereclaim(int active)
 {
-	static Image *i, *ie;
-	int j;
+	static int x, y;
 	ulong np;
+	Image *i;
+	int j;
 
+	np = 0;
+
 	eqlock(&imagealloc.ireclaim);
-	if(i == nil){
-		i = imagealloc.list;
-		ie = &imagealloc.list[conf.nimage];
+
+	/* try reclaim idle images */
+	for(j = 0; j < conf.nimage; j++, x++) {
+		if(x >= conf.nimage)
+			x = 0;
+		i = &imagealloc.list[x];
+		if(i->ref == 0)
+			continue;
+		if(i->s != nil || i->ref != i->pgref)
+			continue;
+		np += pagereclaim(i);
+		if(np >= 1000)
+			goto Done;
 	}
-	np = 0;
-	for(j = 0; j < conf.nimage; j++, i++){
-		if(i >= ie)
-			i = imagealloc.list;
-		if(i->ref == 0 || (i->ref != i->pgref) == !active)
+
+	if(!active)
+		goto Done;
+
+	/* try reclaim active images */
+	for(j = 0; j < conf.nimage; j++, y++) {
+		if(y >= conf.nimage)
+			y = 0;
+		i = &imagealloc.list[y];
+		if(i->ref == 0)
 			continue;
 		np += pagereclaim(i);
 		if(np >= 1000)
--