diff options
author | 2011-07-08 21:00:53 +0000 | |
---|---|---|
committer | 2011-07-08 21:00:53 +0000 | |
commit | 0547f1a4d8730cec4a8c3308eefdad21983bb9ad (patch) | |
tree | e88a4359044ce7e5ad5fcd7be94ad4631cba8023 | |
parent | unlink compat_aout, spotted by jmc (diff) | |
download | wireguard-openbsd-0547f1a4d8730cec4a8c3308eefdad21983bb9ad.tar.xz wireguard-openbsd-0547f1a4d8730cec4a8c3308eefdad21983bb9ad.zip |
Ensure all pages in pmemrange can be marked as dirty.
It'd be a very bad idea to hand out dirty pages as zeroed, just because
we came back from hibernate.
No callers at the moment, will be called on hibernate resume path.
-rw-r--r-- | sys/kern/subr_hibernate.c | 43 | ||||
-rw-r--r-- | sys/sys/hibernate.h | 3 |
2 files changed, 44 insertions, 2 deletions
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c index c622e1a2cb8..7ac3bf26277 100644 --- a/sys/kern/subr_hibernate.c +++ b/sys/kern/subr_hibernate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_hibernate.c,v 1.5 2011/07/08 18:34:46 ariane Exp $ */ +/* $OpenBSD: subr_hibernate.c,v 1.6 2011/07/08 21:00:53 ariane Exp $ */ /* * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl> @@ -264,6 +264,47 @@ uvm_pmr_zero_everything(void) } /* + * Mark all memory as dirty. + * + * Used to inform the system that the clean memory isn't clean for some + * reason, for example because we just came back from hibernate. + */ +void +uvm_pmr_dirty_everything(void) +{ + struct uvm_pmemrange *pmr; + struct vm_page *pg; + int i; + + uvm_lock_fpageq(); + TAILQ_FOREACH(pmr, &uvm.pmr_control.use, pmr_use) { + /* Dirty single pages. */ + while ((pg = TAILQ_FIRST(&pmr->single[UVM_PMR_MEMTYPE_ZERO])) + != NULL) { + uvm_pmr_remove(pmr, pg); + uvm_pagezero(pg); + atomic_clearbits_int(&pg->pg_flags, PG_ZERO); + uvm_pmr_insert(pmr, pg, 0); + } + + /* Dirty multi page ranges. */ + while ((pg = RB_ROOT(&pmr->size[UVM_PMR_MEMTYPE_ZEOR])) + != 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_clearbits_int(&pg[i].pg_flags, PG_ZERO); + } + uvm_pmr_insert(pmr, pg, 0); + } + } + + uvmexp.zeropages = 0; + uvm_unlock_fpageq(); +} + +/* * Allocate the highest address that can hold sz. * * sz in bytes. diff --git a/sys/sys/hibernate.h b/sys/sys/hibernate.h index 64fb36f9fee..8bf90a3ccb5 100644 --- a/sys/sys/hibernate.h +++ b/sys/sys/hibernate.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hibernate.h,v 1.5 2011/07/08 18:34:46 ariane Exp $ */ +/* $OpenBSD: hibernate.h,v 1.6 2011/07/08 21:00:53 ariane Exp $ */ /* * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl> @@ -39,6 +39,7 @@ void *hib_alloc(struct hiballoc_arena*, size_t); void hib_free(struct hiballoc_arena*, void*); int hiballoc_init(struct hiballoc_arena*, void*, size_t len); void uvm_pmr_zero_everything(void); +void uvm_pmr_dirty_everything(void); int uvm_pmr_alloc_pig(paddr_t*, psize_t); int uvm_pmr_alloc_piglet(paddr_t*, psize_t, paddr_t); psize_t uvm_page_rle(paddr_t); |