kernel - Add shutdown method for vm.swapcache
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 6 Apr 2011 04:36:12 +0000 (21:36 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 6 Apr 2011 04:36:12 +0000 (21:36 -0700)
* Add shutdown methods for the swapcache to stop operations during a
  shutdown.  If not stopped swapcache operations can extend beyond the
  device shutdown and cause a crash.

sys/sys/eventhandler.h
sys/vm/vm_swapcache.c

index c334310..147c6fc 100644 (file)
@@ -171,6 +171,8 @@ struct proc;
 typedef void (*shutdown_fn) (void *, int);
 
 #define        SHUTDOWN_PRI_FIRST      EVENTHANDLER_PRI_FIRST
+#define        SHUTDOWN_PRI_SECOND     (EVENTHANDLER_PRI_FIRST + 1)
+#define        SHUTDOWN_PRI_THIRD      (EVENTHANDLER_PRI_FIRST + 2)
 #define        SHUTDOWN_PRI_DEFAULT    EVENTHANDLER_PRI_ANY
 #define        SHUTDOWN_PRI_DRIVER     (EVENTHANDLER_PRI_ANY + 5000)
 #define        SHUTDOWN_PRI_LAST       EVENTHANDLER_PRI_LAST
index e0e8a8a..f291645 100644 (file)
@@ -62,6 +62,7 @@
 #include <sys/vnode.h>
 #include <sys/vmmeter.h>
 #include <sys/sysctl.h>
+#include <sys/eventhandler.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -137,6 +138,19 @@ SYSCTL_QUAD(_vm_swapcache, OID_AUTO, write_count,
        ((int64_t)vm_swap_max * (vm_swapcache_maxswappct + (adj)) / 100)
 
 /*
+ * When shutting down the machine we want to stop swapcache operation
+ * immediately so swap is not accessed after devices have been shuttered.
+ */
+static void
+shutdown_swapcache(void *arg __unused)
+{
+       vm_swapcache_read_enable = 0;
+       vm_swapcache_data_enable = 0;
+       vm_swapcache_meta_enable = 0;
+       wakeup(&vm_swapcache_sleep);    /* shortcut 5-second wait */
+}
+
+/*
  * vm_swapcached is the high level pageout daemon.
  *
  * No requirements.
@@ -153,7 +167,10 @@ vm_swapcached_thread(void)
         * Thread setup
         */
        curthread->td_flags |= TDF_SYSTHREAD;
-
+       EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc,
+                             swapcached_thread, SHUTDOWN_PRI_FIRST);
+       EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_swapcache,
+                             NULL, SHUTDOWN_PRI_SECOND);
        lwkt_gettoken(&vm_token);
        crit_enter();
 
@@ -179,6 +196,11 @@ vm_swapcached_thread(void)
 
        for (;;) {
                /*
+                * Handle shutdown
+                */
+               kproc_suspend_loop();
+
+               /*
                 * Check every 5 seconds when not enabled or if no swap
                 * is present.
                 */