shithub: front

Download patch

ref: 7c12645aba1958a4ece7799c262a835a7fc3e3bb
parent: 8d69e5afcd1fd047ba78cbf93f1ca225d6f92938
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)
--