summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2011-04-06 16:24:24 +0000
committertrasz <trasz@FreeBSD.org>2011-04-06 16:24:24 +0000
commit71afa1f8655bd682a2cce255c7b4b7463f3d3e2b (patch)
treed08a56f9cbf462c82c48125b711186b9d09331af /sys/vm
parent2634e2269f31fe64a28b03dddc844bd7960b8ef6 (diff)
downloadFreeBSD-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/vm')
-rw-r--r--sys/vm/vm_pageout.c42
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) */
OpenPOWER on IntegriCloud