Index | Thread | Search

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

Download raw body.

Thread
> 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?

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