kernel - Fix longstanding VM long-duration stall issues
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 30 Oct 2010 03:58:00 +0000 (20:58 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 30 Oct 2010 04:01:45 +0000 (21:01 -0700)
* The pageout daemon was using the wrong wakeup metrics and essentially
  would not start cleaning out pages until after processes began to
  enter vmwait/vmrate or otherwise begin to stall due to low free memory.

* Fix the metric and also double-check every 5 seconds when the pagedaemon
  statistics wakeup occurs.

* vm.v_free_min + vm.v_cache_min may now be used to tune when the
  pagedaemon is woken up.

sys/vm/vm_pageout.c

index 452bd6d..999d05c 100644 (file)
@@ -1580,14 +1580,18 @@ vm_pageout_thread(void)
                int error;
 
                /*
-                * Wait for an action request
+                * Wait for an action request.  If we timeout check to
+                * see if paging is needed (in case the normal wakeup
+                * code raced us).
                 */
                crit_enter();
                if (vm_pages_needed == 0) {
                        error = tsleep(&vm_pages_needed,
                                       0, "psleep",
                                       vm_pageout_stats_interval * hz);
-                       if (error && vm_pages_needed == 0) {
+                       if (error &&
+                           vm_paging_needed() == 0 &&
+                           vm_pages_needed == 0) {
                                vm_pageout_page_stats();
                                continue;
                        }
@@ -1663,9 +1667,9 @@ SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start, &page_kp)
  * to possibly wake the pagedaemon up to replentish our supply.
  *
  * We try to generate some hysteresis by waking the pagedaemon up
- * when our free+cache pages go below the severe level.  The pagedaemon
- * tries to get the count back up to at least the minimum, and through
- * to the target level if possible.
+ * when our free+cache pages go below the free_min+cache_min level.
+ * The pagedaemon tries to get the count back up to at least the
+ * minimum, and through to the target level if possible.
  *
  * If the pagedaemon is already active bump vm_pages_needed as a hint
  * that there are even more requests pending.
@@ -1676,12 +1680,12 @@ SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start, &page_kp)
 void
 pagedaemon_wakeup(void)
 {
-       if (vm_page_count_severe() && curthread != pagethread) {
+       if (vm_paging_needed() && curthread != pagethread) {
                if (vm_pages_needed == 0) {
-                       vm_pages_needed = 1;
+                       vm_pages_needed = 1;    /* SMP race ok */
                        wakeup(&vm_pages_needed);
                } else if (vm_page_count_min(0)) {
-                       ++vm_pages_needed;
+                       ++vm_pages_needed;      /* SMP race ok */
                }
        }
 }