On 26/09/25(Fri) 07:46, Miod Vallat wrote:
> > 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 was hopping to see in your trace what arguments are given to the
physical allocator. IMHO we should sleep on `uvmexp.free' as much as
possible. In the case of landisk the VFS is not allocating with any
constraint so it should be possible.
> I am testing the third chunk at the moment.
That is the real fix.
> > 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();
> > }
> > }
> >
> >