Index | Thread | Search

From:
Martin Pieuchot <mpi@grenadille.net>
Subject:
Re: OOM, page daemon & responsiveness
To:
Mark Kettenis <mark.kettenis@xs4all.nl>
Cc:
tech@openbsd.org, sthen@openbsd.org
Date:
Mon, 30 Sep 2024 12:34:08 +0200

Download raw body.

Thread
On 30/09/24(Mon) 12:20, Mark Kettenis wrote:
> > Date: Mon, 30 Sep 2024 10:39:55 +0200
> > From: Martin Pieuchot <mpi@grenadille.net>
> > 
> > I observed that the "freezes" happening when the page daemon is freeing
> > memory are almost always due to a large scan of inactive pages.  During
> > such scans, the kernel lock is held and most processes are waiting for
> > physical pages.
> > 
> > The diff below reduces the duration of such scans by removing a change
> > which wasn't present in 4.4BSD VM's and brings back coherency regarding
> > free pages watermarks.
> 
> So this was brought in from NetBSD many moons ago.  It was introduced
> in NetBSD with the following commit:
> 
>  https://github.com/NetBSD/src/commit/92045bbba9323e7368f3e85519dbacb9973a0eb1
> 
> I guess the relevant bit of the commit message is:
> 
>  - start 4 times as many pageouts as we need free pages.
>    this should reduce latency in low-memory situations.
> 
> In view of what we observe, it seems it does the opposite?

Indeed because we're now dealing with multiple Gb of RAM.  The logic
that might have been good enough at some point in time is no longer
working as expected.  All the conditions at the limits should be
revisited, I'm planing to do that.

> > This diff makes the page daemon stop scanning as soon as the high water
> > mark has been reached.
> > 
> > Even if this might not be considered a real fix and we could do much
> > better by adapting the logic to today's amount of RAM, it is a step in
> > such direction because it brings back the original & coherent logic.
> > 
> > ok?
> 
> ok kettenis@
> 
> > Index: uvm/uvm_pdaemon.c
> > ===================================================================
> > RCS file: /cvs/src/sys/uvm/uvm_pdaemon.c,v
> > diff -u -p -r1.115 uvm_pdaemon.c
> > --- uvm/uvm_pdaemon.c	30 Sep 2024 08:09:39 -0000	1.115
> > +++ uvm/uvm_pdaemon.c	30 Sep 2024 08:17:00 -0000
> > @@ -468,7 +468,7 @@ uvmpd_scan_inactive(struct uvm_pmalloc *
> >  			 */
> >  			free = uvmexp.free - BUFPAGES_DEFICIT;
> >  			if (((pma == NULL || (pma->pm_flags & UVM_PMA_FREED)) &&
> > -			    (free + uvmexp.paging >= uvmexp.freetarg << 2)) ||
> > +			    (free + uvmexp.paging >= uvmexp.freetarg)) ||
> >  			    dirtyreacts == UVMPD_NUMDIRTYREACTS) {
> >  				if (swslot == 0) {
> >  					/* exit now if no swap-i/o pending */
> > @@ -565,7 +565,7 @@ uvmpd_scan_inactive(struct uvm_pmalloc *
> >  			 * free target when all the current pageouts complete.
> >  			 */
> >  			if ((pma == NULL || (pma->pm_flags & UVM_PMA_FREED)) &&
> > -			    (free + uvmexp.paging > uvmexp.freetarg << 2)) {
> > +			    (free + uvmexp.paging > uvmexp.freetarg)) {
> >  				rw_exit(slock);
> >  				continue;
> >  			}
> > 
> >