From: Mark Kettenis Subject: Re: OOM, page daemon & responsiveness To: Martin Pieuchot Cc: tech@openbsd.org, sthen@openbsd.org Date: Mon, 30 Sep 2024 12:20:13 +0200 > Date: Mon, 30 Sep 2024 10:39:55 +0200 > From: Martin Pieuchot > > 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; > } > >