Author: kib
Date: Mon Aug 27 09:39:34 2018
New Revision: 338335
URL: https://svnweb.freebsd.org/changeset/base/338335

Log:
  MFC r337714:
  Prevent some parallel swap-ins, rate-limit swapper swap-ins.

Modified:
  stable/11/sys/vm/vm_swapout.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/vm/vm_swapout.c
==============================================================================
--- stable/11/sys/vm/vm_swapout.c       Mon Aug 27 07:32:41 2018        
(r338334)
+++ stable/11/sys/vm/vm_swapout.c       Mon Aug 27 09:39:34 2018        
(r338335)
@@ -157,6 +157,8 @@ static struct mtx vm_daemon_mtx;
 MTX_SYSINIT(vm_daemon, &vm_daemon_mtx, "vm daemon", MTX_DEF);
 
 static int swapped_cnt;
+static int swap_inprogress;    /* Pending swap-ins done outside swapper. */
+static int last_swapin;
 
 static void swapclear(struct proc *);
 static int swapout(struct proc *);
@@ -625,6 +627,8 @@ faultin(struct proc *p)
                sx_xlock(&allproc_lock);
                MPASS(swapped_cnt > 0);
                swapped_cnt--;
+               if (curthread != &thread0)
+                       swap_inprogress++;
                sx_xunlock(&allproc_lock);
 
                /*
@@ -635,6 +639,13 @@ faultin(struct proc *p)
                FOREACH_THREAD_IN_PROC(p, td)
                        vm_thread_swapin(td, oom_alloc);
 
+               if (curthread != &thread0) {
+                       sx_xlock(&allproc_lock);
+                       MPASS(swap_inprogress > 0);
+                       swap_inprogress--;
+                       last_swapin = ticks;
+                       sx_xunlock(&allproc_lock);
+               }
                PROC_LOCK(p);
                swapclear(p);
                p->p_swtick = ticks;
@@ -652,18 +663,17 @@ faultin(struct proc *p)
  */
 
 static struct proc *
-swapper_selector(void)
+swapper_selector(bool wkilled_only)
 {
        struct proc *p, *res;
        struct thread *td;
-       int min_flag, ppri, pri, slptime, swtime;
+       int ppri, pri, slptime, swtime;
 
        sx_assert(&allproc_lock, SA_SLOCKED);
        if (swapped_cnt == 0)
                return (NULL);
        res = NULL;
        ppri = INT_MIN;
-       min_flag = vm_page_count_min();
        FOREACH_PROC_IN_SYSTEM(p) {
                PROC_LOCK(p);
                if (p->p_state == PRS_NEW || (p->p_flag & (P_SWAPPINGOUT |
@@ -681,7 +691,7 @@ swapper_selector(void)
                         */
                        return (p);
                }
-               if (min_flag) {
+               if (wkilled_only) {
                        PROC_UNLOCK(p);
                        continue;
                }
@@ -712,11 +722,29 @@ swapper_selector(void)
                }
                PROC_UNLOCK(p);
        }
+
        if (res != NULL)
                PROC_LOCK(res);
        return (res);
 }
 
+#define        SWAPIN_INTERVAL (MAXSLP * hz / 2)
+
+/*
+ * Limit swapper to swap in one non-WKILLED process in MAXSLP/2
+ * interval, assuming that there is:
+ * - no memory shortage;
+ * - no parallel swap-ins;
+ * - no other swap-ins in the current SWAPIN_INTERVAL.
+ */
+static bool
+swapper_wkilled_only(void)
+{
+
+       return (vm_page_count_min() || swap_inprogress > 0 ||
+           (u_int)(ticks - last_swapin) < SWAPIN_INTERVAL);
+}
+
 void
 swapper(void)
 {
@@ -724,11 +752,11 @@ swapper(void)
 
        for (;;) {
                sx_slock(&allproc_lock);
-               p = swapper_selector();
+               p = swapper_selector(swapper_wkilled_only());
                sx_sunlock(&allproc_lock);
 
                if (p == NULL) {
-                       tsleep(&proc0, PVM, "swapin", MAXSLP * hz / 2);
+                       tsleep(&proc0, PVM, "swapin", SWAPIN_INTERVAL);
                } else {
                        PROC_LOCK_ASSERT(p, MA_OWNED);
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to