> Diff below includes a fix for a missing wakeup. It might correspond to
> the bug you're seeing.
>
> Problem is that there are two sleep channels and two mechanism for OOM
> situations. The IOdone daemon was waking only one of the two.
>
> Does it help?
The first two chunks make things worse and make everything stuck as soon
as one processes hit pmrwait.
I am testing the third chunk at the moment.
> 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
> @@ -303,10 +303,10 @@ uvm_pageout(void *arg)
> * wake up any waiters.
> */
> uvm_lock_fpageq();
> - if (uvmexp.free > uvmexp.reserve_kernel || uvmexp.paging == 0) {
> - wakeup(&uvmexp.free);
> - }
> -
> + /*
> + * Wake waiter on pma first because they are more likely
> + * to starve on low pages.
> + */
> if (pma != NULL) {
> /*
> * XXX If UVM_PMA_FREED isn't set, no pages
> @@ -320,8 +320,11 @@ uvm_pageout(void *arg)
> wakeup(pma);
> }
> }
> + if (uvmexp.free > uvmexp.reserve_kernel || uvmexp.paging == 0)
> + wakeup(&uvmexp.free);
> uvm_unlock_fpageq();
>
> +
> /*
> * scan done. unlock page queues (the only lock we are holding)
> */
> @@ -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();
> }
> }
>
>