Author: trasz
Date: Wed Apr  6 16:24:24 2011
New Revision: 220386
URL: http://svn.freebsd.org/changeset/base/220386

Log:
  Add RACCT_RSS.
  
  Sponsored by: The FreeBSD Foundation
  Reviewed by:  kib (earlier version)

Modified:
  head/sys/vm/vm_pageout.c

Modified: head/sys/vm/vm_pageout.c
==============================================================================
--- head/sys/vm/vm_pageout.c    Wed Apr  6 15:45:32 2011        (r220385)
+++ head/sys/vm/vm_pageout.c    Wed Apr  6 16:24:24 2011        (r220386)
@@ -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) */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to