summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_glue.c')
-rw-r--r--sys/vm/vm_glue.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 6ac6a96..e38b3d3 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -91,6 +91,7 @@
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
#include <vm/vm_pager.h>
+#include <vm/swap_pager.h>
#include <sys/user.h>
@@ -324,6 +325,45 @@ vm_proc_swapin(struct proc *p)
up = (vm_offset_t)p->p_uarea;
pmap_qenter(up, ma, UAREA_PAGES);
}
+
+/*
+ * Swap in the UAREAs of all processes swapped out to the given device.
+ * The pages in the UAREA are marked dirty and their swap metadata is freed.
+ */
+void
+vm_proc_swapin_all(int devidx)
+{
+ struct proc *p;
+ vm_object_t object;
+ vm_page_t m;
+
+retry:
+ sx_slock(&allproc_lock);
+ FOREACH_PROC_IN_SYSTEM(p) {
+ PROC_LOCK(p);
+ mtx_lock_spin(&sched_lock);
+
+ object = p->p_upages_obj;
+ if (object != NULL &&
+ swap_pager_isswapped(p->p_upages_obj, devidx)) {
+ sx_sunlock(&allproc_lock);
+ faultin(p);
+ mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ vm_page_lock_queues();
+ TAILQ_FOREACH(m, &object->memq, listq)
+ vm_page_dirty(m);
+ vm_page_unlock_queues();
+ swap_pager_freespace(object, 0,
+ object->un_pager.swp.swp_bcount);
+ goto retry;
+ }
+
+ mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(p);
+ }
+ sx_sunlock(&allproc_lock);
+}
#endif
/*
OpenPOWER on IntegriCloud