diff options
Diffstat (limited to 'sys/kern/subr_hibernate.c')
-rw-r--r-- | sys/kern/subr_hibernate.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c index 51d376b126e..f9159b5853e 100644 --- a/sys/kern/subr_hibernate.c +++ b/sys/kern/subr_hibernate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_hibernate.c,v 1.1 2011/07/08 17:58:16 ariane Exp $ */ +/* $OpenBSD: subr_hibernate.c,v 1.2 2011/07/08 18:20:10 ariane Exp $ */ /* * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl> @@ -21,6 +21,7 @@ #include <sys/tree.h> #include <sys/types.h> #include <sys/systm.h> +#include <uvm/uvm.h> /* @@ -222,3 +223,42 @@ hiballoc_init(struct hiballoc_arena *arena, void *p_ptr, size_t p_len) return 0; } + + +/* + * Zero all free memory. + */ +void +uvm_pmr_zero_everything(void) +{ + struct uvm_pmemrange *pmr; + struct vm_page *pg; + int i; + + uvm_lock_fpageq(); + TAILQ_FOREACH(pmr, &uvm.pmr_control.use, pmr_use) { + /* Zero single pages. */ + while ((pg = TAILQ_FIRST(&pmr->single[UVM_PMR_MEMTYPE_DIRTY])) + != NULL) { + uvm_pmr_remove(pmr, pg); + uvm_pagezero(pg); + atomic_setbits_int(&pg->pg_flags, PG_ZERO); + uvmexp.zeropages++; + uvm_pmr_insert(pmr, pg, 0); + } + + /* Zero multi page ranges. */ + while ((pg = RB_ROOT(&pmr->size[UVM_PMR_MEMTYPE_DIRTY])) + != NULL) { + pg--; /* Size tree always has second page. */ + uvm_pmr_remove(pmr, pg); + for (i = 0; i < pg->fpgsz; i++) { + uvm_pagezero(&pg[i]); + atomic_setbits_int(&pg[i].pg_flags, PG_ZERO); + uvmexp.zeropages++; + } + uvm_pmr_insert(pmr, pg, 0); + } + } + uvm_unlock_fpageq(); +} |