Index | Thread | Search

From:
Martin Pieuchot <mpi@grenadille.net>
Subject:
missing wakeup in pdaemon (fix for release)
To:
sthen@openbsd.org, miod@openbsd.org, kettenis@openbsd.org, deraadt@openbsd.org
Cc:
tech@openbsd.org
Date:
Mon, 29 Sep 2025 09:37:31 +0200

Download raw body.

Thread
When a process waits for physical pages inside the pmemrange allocator
it sleeps on a per-thread channel reported as "pmrwait" in top(1).  This
channel has been introduced with the memory partitioning to let the VFS
get "low" DMA pages.

Even on machines without memory partitioning, like landisk, this channel
is used.  Since the daemon finishing Asynchronous IOs for swapped pages,
has never been aware of this new mechanism, processes waiting inside the
pmemrange allocator might end up sleeping forever.

Diff below fixes this.

I'd appreciate if this could be stress tested on workloads known to
swap.

ok?

Thanks,
Martin

Index: uvm/uvm_pdaemon.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_pdaemon.c,v
diff -u -p -r1.137 uvm_pdaemon.c
--- uvm/uvm_pdaemon.c	2 Jun 2025 18:49:04 -0000	1.137
+++ uvm/uvm_pdaemon.c	24 Sep 2025 10:11:11 -0000
@@ -377,8 +380,11 @@ uvm_aiodone_daemon(void *arg)
 
 		uvm_lock_fpageq();
 		atomic_sub_int(&uvmexp.paging, npages);
-		wakeup(uvmexp.free <= uvmexp.reserve_kernel ? &uvm.pagedaemon :
-		    &uvmexp.free);
+		if (uvmexp.free <= uvmexp.reserve_kernel ||
+		    !TAILQ_EMPTY(&uvm.pmr_control.allocs))
+			wakeup(&uvm.pagedaemon);
+		else
+			wakeup(&uvmexp.free);
 		uvm_unlock_fpageq();
 	}
 }