git: 9front

Download patch

ref: cd434df700c9136aba260c6b2467a46056db4281
parent: 85b89f574397db1e192a4bd25066cb2c587647f5
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Mar 15 11:05:34 EDT 2026

kernel: fix newpage() and pager wakeup()

The pager must be woken up when freecount drops <= swapalloc.highwater.

Pager continues to run until freecount >= swapalloc.headroom.

freepages() wakes up sleeping newpage() procs when freecount *was* <= swapalloc.highwater,
only wake up pwait[1] queue when freecount *becomes* > swapcount.highwater, always wake
up pwait[0] (noswappers).

Remove spurious wakeup calls in devswap.

--- a/sys/src/9/port/devswap.c
+++ b/sys/src/9/port/devswap.c
@@ -213,8 +213,6 @@
 		up->psstate = "Reclaim";
 		if(reclaim()){
 			up->psstate = "Idle";
-			wakeup(&palloc.pwait[0]);
-			wakeup(&palloc.pwait[1]);
 			sleep(&swapalloc.r, needpages, nil);
 			continue;
 		}
--- a/sys/src/9/port/page.c
+++ b/sys/src/9/port/page.c
@@ -76,15 +76,6 @@
 	print("%lldM swap\n", v/(1024*1024));
 }
 
-static void
-pagechaindone(void)
-{
-	if(palloc.pwait[0].p != nil && wakeup(&palloc.pwait[0]) != nil)
-		return;
-	if(palloc.pwait[1].p != nil)
-		wakeup(&palloc.pwait[1]);
-}
-
 void
 freepages(Page *head, Page *tail, ulong np)
 {
@@ -102,8 +93,14 @@
 	lock(&palloc);
 	tail->next = palloc.head;
 	palloc.head = head;
-	palloc.freecount += np;
-	pagechaindone();
+	if(palloc.freecount <= swapalloc.highwater){
+		palloc.freecount += np;
+		if(palloc.freecount > swapalloc.highwater)
+			wakeup(&palloc.pwait[1]);
+		wakeup(&palloc.pwait[0]);
+	} else {
+		palloc.freecount += np;
+	}
 	unlock(&palloc);
 }
 
@@ -186,12 +183,11 @@
 		if(locked)
 			qunlock(locked);
 
-		kickpager();
 		if(!waserror()){
 			Rendezq *q;
 
 			q = &palloc.pwait[!up->noswap];
-			eqlock(q);	
+			eqlock(q);
 			if(!waserror()){
 				sleep(q, havepages, nil);
 				poperror();
@@ -228,8 +224,12 @@
 
 	*l = p->next;
 	p->next = nil;
-	palloc.freecount--;
-	unlock(&palloc);
+	if(--palloc.freecount <= swapalloc.highwater){
+		unlock(&palloc);
+		kickpager();
+	} else {
+		unlock(&palloc);
+	}
 
 	p->ref = 1;
 	p->va = va;
--