-/* $OpenBSD: uvm_pdaemon.c,v 1.109 2023/10/27 19:18:53 mpi Exp $ */
+/* $OpenBSD: uvm_pdaemon.c,v 1.110 2024/03/24 10:29:35 mpi Exp $ */
/* $NetBSD: uvm_pdaemon.c,v 1.23 2000/08/20 10:24:14 bjh21 Exp $ */
/*
/*
* uvmpd_tune: tune paging parameters
- *
- * => called whenever memory is added to (or removed from?) the system
- * => caller must call with page queues locked
*/
-
void
uvmpd_tune(void)
{
+ int val;
- uvmexp.freemin = uvmexp.npages / 30;
+ val = uvmexp.npages / 30;
- /* between 16k and 512k */
/* XXX: what are these values good for? */
- uvmexp.freemin = max(uvmexp.freemin, (16*1024) >> PAGE_SHIFT);
-#if 0
- uvmexp.freemin = min(uvmexp.freemin, (512*1024) >> PAGE_SHIFT);
-#endif
+ val = max(val, (16*1024) >> PAGE_SHIFT);
/* Make sure there's always a user page free. */
- if (uvmexp.freemin < uvmexp.reserve_kernel + 1)
- uvmexp.freemin = uvmexp.reserve_kernel + 1;
-
- uvmexp.freetarg = (uvmexp.freemin * 4) / 3;
- if (uvmexp.freetarg <= uvmexp.freemin)
- uvmexp.freetarg = uvmexp.freemin + 1;
+ if (val < uvmexp.reserve_kernel + 1)
+ val = uvmexp.reserve_kernel + 1;
+ uvmexp.freemin = val;
- /* uvmexp.inactarg: computed in main daemon loop */
+ /* Calculate free target. */
+ val = (uvmexp.freemin * 4) / 3;
+ if (val <= uvmexp.freemin)
+ val = uvmexp.freemin + 1;
+ uvmexp.freetarg = val;
uvmexp.wiredmax = uvmexp.npages / 3;
}
{
struct uvm_constraint_range constraint;
struct uvm_pmalloc *pma;
- int npages = 0;
+ int free;
/* ensure correct priority and set paging parameters... */
uvm.pagedaemon_proc = curproc;
(void) spl0();
- uvm_lock_pageq();
- npages = uvmexp.npages;
uvmpd_tune();
- uvm_unlock_pageq();
for (;;) {
long size;
} else
constraint = no_constraint;
}
-
+ free = uvmexp.free - BUFPAGES_DEFICIT;
uvm_unlock_fpageq();
/*
* now lock page queues and recompute inactive count
*/
uvm_lock_pageq();
- if (npages != uvmexp.npages) { /* check for new pages? */
- npages = uvmexp.npages;
- uvmpd_tune();
- }
-
uvmexp.inactarg = (uvmexp.active + uvmexp.inactive) / 3;
if (uvmexp.inactarg <= uvmexp.freetarg) {
uvmexp.inactarg = uvmexp.freetarg + 1;
}
+ uvm_unlock_pageq();
/* Reclaim pages from the buffer cache if possible. */
size = 0;
if (pma != NULL)
size += pma->pm_size >> PAGE_SHIFT;
- if (uvmexp.free - BUFPAGES_DEFICIT < uvmexp.freetarg)
- size += uvmexp.freetarg - (uvmexp.free -
- BUFPAGES_DEFICIT);
+ if (free < uvmexp.freetarg)
+ size += uvmexp.freetarg - free;
if (size == 0)
size = 16; /* XXX */
- uvm_unlock_pageq();
+
(void) bufbackoff(&constraint, size * 2);
#if NDRM > 0
drmbackoff(size * 2);
#endif
- uvm_lock_pageq();
-
/*
* scan if needed
*/
- if (pma != NULL ||
- ((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freetarg) ||
+ uvm_lock_pageq();
+ free = uvmexp.free - BUFPAGES_DEFICIT;
+ if (pma != NULL || (free < uvmexp.freetarg) ||
((uvmexp.inactive + BUFPAGES_INACT) < uvmexp.inactarg)) {
uvmpd_scan(pma, &constraint);
}
-/* $OpenBSD: uvmexp.h,v 1.11 2023/10/27 19:18:53 mpi Exp $ */
+/* $OpenBSD: uvmexp.h,v 1.12 2024/03/24 10:29:35 mpi Exp $ */
#ifndef _UVM_UVMEXP_
#define _UVM_UVMEXP_
* I immutable after creation
* K kernel lock
* F uvm_lock_fpageq
+ * L uvm_lock_pageq
* S uvm_swap_data_lock
+ * p copy of per-CPU counters, used only by userland.
*/
struct uvmexp {
/* vm_page constants */
/* vm_page counters */
int npages; /* [I] number of pages we manage */
int free; /* [F] number of free pages */
- int active; /* number of active pages */
- int inactive; /* number of pages that we free'd but may want back */
+ int active; /* [L] # of active pages */
+ int inactive; /* [L] # of pages that we free'd but may want back */
int paging; /* number of pages in the process of being paged out */
int wired; /* number of wired pages */
int vtextpages; /* XXX # of pages used by vtext vnodes */
/* pageout params */
- int freemin; /* min number of free pages */
- int freetarg; /* target number of free pages */
+ int freemin; /* [I] min number of free pages */
+ int freetarg; /* [I] target number of free pages */
int inactarg; /* target number of inactive pages */
- int wiredmax; /* max number of wired pages */
+ int wiredmax; /* [I] max number of wired pages */
int anonmin; /* min threshold for anon pages */
int vtextmin; /* min threshold for vtext pages */
int vnodemin; /* min threshold for vnode pages */
int unused06; /* formerly nfreeanon */
/* stat counters */
- int faults; /* page fault count */
+ int faults; /* [p] page fault count */
int traps; /* trap count */
int intrs; /* interrupt count */
int swtch; /* context switch count */
int softs; /* software interrupt count */
int syscalls; /* system calls */
- int pageins; /* pagein operation count */
+ int pageins; /* [p] pagein operation count */
/* pageouts are in pdpageouts below */
- int unused07; /* formerly obsolete_swapins */
- int unused08; /* formerly obsolete_swapouts */
+ int unused07; /* formerly obsolete_swapins */
+ int unused08; /* formerly obsolete_swapouts */
int pgswapin; /* pages swapped in */
int pgswapout; /* pages swapped out */
int forks; /* forks */
int unused09; /* formerly zeroaborts */
/* fault subcounters */
- int fltnoram; /* number of times fault was out of ram */
- int fltnoanon; /* number of times fault was out of anons */
- int fltnoamap; /* number of times fault was out of amap chunks */
- int fltpgwait; /* number of times fault had to wait on a page */
- int fltpgrele; /* number of times fault found a released page */
- int fltrelck; /* number of times fault relock called */
- int fltrelckok; /* number of times fault relock is a success */
- int fltanget; /* number of times fault gets anon page */
- int fltanretry; /* number of times fault retrys an anon get */
- int fltamcopy; /* number of times fault clears "needs copy" */
- int fltnamap; /* number of times fault maps a neighbor anon page */
- int fltnomap; /* number of times fault maps a neighbor obj page */
- int fltlget; /* number of times fault does a locked pgo_get */
- int fltget; /* number of times fault does an unlocked get */
- int flt_anon; /* number of times fault anon (case 1a) */
- int flt_acow; /* number of times fault anon cow (case 1b) */
- int flt_obj; /* number of times fault is on object page (2a) */
- int flt_prcopy; /* number of times fault promotes with copy (2b) */
- int flt_przero; /* number of times fault promotes with zerofill (2b) */
+ int fltnoram; /* [p] # of times fault was out of ram */
+ int fltnoanon; /* [p] # of times fault was out of anons */
+ int fltnoamap; /* [p] # of times fault was out of amap chunks */
+ int fltpgwait; /* [p] # of times fault had to wait on a page */
+ int fltpgrele; /* [p] # of times fault found a released page */
+ int fltrelck; /* [p] # of times fault relock called */
+ int fltrelckok; /* [p] # of times fault relock is a success */
+ int fltanget; /* [p] # of times fault gets anon page */
+ int fltanretry; /* [p] # of times fault retrys an anon get */
+ int fltamcopy; /* [p] # of times fault clears "needs copy" */
+ int fltnamap; /* [p] # of times fault maps a neighbor anon page */
+ int fltnomap; /* [p] # of times fault maps a neighbor obj page */
+ int fltlget; /* [p] # of times fault does a locked pgo_get */
+ int fltget; /* [p] # of times fault does an unlocked get */
+ int flt_anon; /* [p] # of times fault anon (case 1a) */
+ int flt_acow; /* [p] # of times fault anon cow (case 1b) */
+ int flt_obj; /* [p] # of times fault is on object page (2a) */
+ int flt_prcopy; /* [p] # of times fault promotes with copy (2b) */
+ int flt_przero; /* [p] # of times fault promotes with zerofill (2b) */
/* daemon counters */
- int pdwoke; /* number of times daemon woke up */
+ int pdwoke; /* [F] # of times daemon woke up */
int pdrevs; /* number of times daemon rev'd clock hand */
int pdswout; /* number of times daemon called for swapout */
int pdfreed; /* number of pages daemon freed since boot */