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;
--
⑨