diff options
author | trasz <trasz@FreeBSD.org> | 2011-04-06 16:24:24 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2011-04-06 16:24:24 +0000 |
commit | 71afa1f8655bd682a2cce255c7b4b7463f3d3e2b (patch) | |
tree | d08a56f9cbf462c82c48125b711186b9d09331af /sys | |
parent | 2634e2269f31fe64a28b03dddc844bd7960b8ef6 (diff) | |
download | FreeBSD-src-71afa1f8655bd682a2cce255c7b4b7463f3d3e2b.zip FreeBSD-src-71afa1f8655bd682a2cce255c7b4b7463f3d3e2b.tar.gz |
Add RACCT_RSS.
Sponsored by: The FreeBSD Foundation
Reviewed by: kib (earlier version)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/vm/vm_pageout.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index a780f39..7ffae4e 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kthread.h> #include <sys/ktr.h> #include <sys/mount.h> +#include <sys/racct.h> #include <sys/resourcevar.h> #include <sys/sched.h> #include <sys/signalvar.h> @@ -1631,11 +1632,16 @@ vm_daemon() struct proc *p; struct thread *td; struct vmspace *vm; - int breakout, swapout_flags; + int breakout, swapout_flags, tryagain, attempts; + uint64_t rsize, ravailable; while (TRUE) { mtx_lock(&vm_daemon_mtx); +#ifdef RACCT + msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", hz); +#else msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", 0); +#endif swapout_flags = vm_pageout_req_swapout; vm_pageout_req_swapout = 0; mtx_unlock(&vm_daemon_mtx); @@ -1646,6 +1652,10 @@ vm_daemon() * scan the processes for exceeding their rlimits or if * process is swapped out -- deactivate pages */ + tryagain = 0; + attempts = 0; +again: + attempts++; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { vm_pindex_t limit, size; @@ -1704,9 +1714,39 @@ vm_daemon() vm_pageout_map_deactivate_pages( &vm->vm_map, limit); } + rsize = IDX_TO_OFF(size); + PROC_LOCK(p); + racct_set(p, RACCT_RSS, rsize); + ravailable = racct_get_available(p, RACCT_RSS); + PROC_UNLOCK(p); + if (rsize > ravailable) { + /* + * Don't be overly aggressive; this might be + * an innocent process, and the limit could've + * been exceeded by some memory hog. Don't + * try to deactivate more than 1/4th of process' + * resident set size. + */ + if (attempts <= 8) { + if (ravailable < rsize - (rsize / 4)) + ravailable = rsize - (rsize / 4); + } + vm_pageout_map_deactivate_pages( + &vm->vm_map, OFF_TO_IDX(ravailable)); + /* Update RSS usage after paging out. */ + size = vmspace_resident_count(vm); + rsize = IDX_TO_OFF(size); + PROC_LOCK(p); + racct_set(p, RACCT_RSS, rsize); + PROC_UNLOCK(p); + if (rsize > ravailable) + tryagain = 1; + } vmspace_free(vm); } sx_sunlock(&allproc_lock); + if (tryagain != 0 && attempts <= 10) + goto again; } } #endif /* !defined(NO_SWAPPING) */ |