diff options
author | 2011-04-03 22:07:37 +0000 | |
---|---|---|
committer | 2011-04-03 22:07:37 +0000 | |
commit | 205bb46da6adb871d9864633a3fa3527e6063831 (patch) | |
tree | ef3ff8925c818d5dac7d66e5cfc1707744455a53 | |
parent | Call setlocale() to avoid display glitches in UTF-8 locales. (diff) | |
download | wireguard-openbsd-205bb46da6adb871d9864633a3fa3527e6063831.tar.xz wireguard-openbsd-205bb46da6adb871d9864633a3fa3527e6063831.zip |
Helper functions for suspend.
Allow reclaiming pages from all pools.
Allow zeroing all pages.
Allocate the more equal pig.
mlarking@ needs this.
Not called yet.
ok mlarkin@, theo@
-rw-r--r-- | sys/kern/subr_pool.c | 14 | ||||
-rw-r--r-- | sys/sys/pool.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_pmemrange.c | 94 | ||||
-rw-r--r-- | sys/uvm/uvm_pmemrange.h | 7 |
4 files changed, 114 insertions, 4 deletions
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c index 2c201661948..c7d85ff0f23 100644 --- a/sys/kern/subr_pool.c +++ b/sys/kern/subr_pool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_pool.c,v 1.99 2010/11/03 17:49:42 mikeb Exp $ */ +/* $OpenBSD: subr_pool.c,v 1.100 2011/04/03 22:07:37 ariane Exp $ */ /* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */ /*- @@ -1069,6 +1069,18 @@ pool_reclaim(struct pool *pp) return (1); } +/* + * Release all complete pages that have not been used recently + * from all pools. + */ +void +pool_reclaim_all(void) +{ + struct pool *pp; + TAILQ_FOREACH(pp, &pool_head, pr_poollist) + pool_reclaim(pp); +} + #ifdef DDB #include <machine/db_machdep.h> #include <ddb/db_interface.h> diff --git a/sys/sys/pool.h b/sys/sys/pool.h index db9c9bebaa8..c5b8291fa8e 100644 --- a/sys/sys/pool.h +++ b/sys/sys/pool.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pool.h,v 1.36 2010/09/26 21:03:57 tedu Exp $ */ +/* $OpenBSD: pool.h,v 1.37 2011/04/03 22:07:37 ariane Exp $ */ /* $NetBSD: pool.h,v 1.27 2001/06/06 22:00:17 rafal Exp $ */ /*- @@ -157,6 +157,7 @@ void pool_set_ctordtor(struct pool *, int (*)(void *, void *, int), void *pool_get(struct pool *, int) __malloc; void pool_put(struct pool *, void *); int pool_reclaim(struct pool *); +void pool_reclaim_all(void); int pool_prime(struct pool *, int); #ifdef DDB diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c index 7679fe58b33..b029fc1d770 100644 --- a/sys/uvm/uvm_pmemrange.c +++ b/sys/uvm/uvm_pmemrange.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pmemrange.c,v 1.18 2010/08/28 22:27:47 miod Exp $ */ +/* $OpenBSD: uvm_pmemrange.c,v 1.19 2011/04/03 22:07:37 ariane Exp $ */ /* * Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl> @@ -1833,3 +1833,95 @@ uvm_pmr_print(void) printf("#ranges = %d\n", useq_len); } #endif + +#ifndef SMALL_KERNEL +/* + * Zero all free memory. + */ +void +uvm_pmr_zero_everything(void) +{ + struct uvm_pmemrange *pmr; + struct vm_page *pg; + int i; + psize_t zeroed = 0; + + 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); + + zeroed++; /* DEBUG */ + + if (zeroed % 1000) + printf("1"); + } + + /* 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); + + zeroed++; /* DEBUG */ + if (zeroed % 100) + printf("L"); + } + } + uvm_unlock_fpageq(); +} + +/* + * Allocate the biggest contig chunk of memory. + */ +int +uvm_pmr_alloc_pig(paddr_t *addr, psize_t *sz) +{ + struct uvm_pmemrange *pig_pmr, *pmr; + struct vm_page *pig_pg, *pg; + int memtype; + + uvm_lock_fpageq(); + pig_pg = NULL; + TAILQ_FOREACH(pmr, &uvm.pmr_control.use, pmr_use) { + for (memtype = 0; memtype < UVM_PMR_MEMTYPE_MAX; memtype++) { + /* Find biggest page in this memtype pmr. */ + pg = RB_MAX(uvm_pmr_size, &pmr->size[memtype]); + if (pg == NULL) + pg = TAILQ_FIRST(&pmr->single[memtype]); + + if (pig_pg == NULL || (pg != NULL && pig_pg != NULL && + pig_pg->fpgsz < pg->fpgsz)) { + pig_pmr = pmr; + pig_pg = pg; + } + } + } + + /* Remove page from freelist. */ + if (pig_pg != NULL) { + uvm_pmr_remove(pig_pmr, pig_pg); + uvmexp.free -= pig_pg->fpgsz; + if (pig_pg->pg_flags & PG_ZERO) + uvmexp.zeropages -= pig_pg->fpgsz; + *addr = VM_PAGE_TO_PHYS(pig_pg); + *sz = pig_pg->fpgsz; + } + uvm_unlock_fpageq(); + + /* Return. */ + return (pig_pg != NULL ? 0 : ENOMEM); +} +#endif /* SMALL_KERNEL */ diff --git a/sys/uvm/uvm_pmemrange.h b/sys/uvm/uvm_pmemrange.h index 100b47c6f43..fa27540e77d 100644 --- a/sys/uvm/uvm_pmemrange.h +++ b/sys/uvm/uvm_pmemrange.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pmemrange.h,v 1.6 2011/04/03 14:16:42 guenther Exp $ */ +/* $OpenBSD: uvm_pmemrange.h,v 1.7 2011/04/03 22:07:37 ariane Exp $ */ /* * Copyright (c) 2009 Ariane van der Steldt <ariane@stack.nl> @@ -80,4 +80,9 @@ void uvm_pmr_init(void); int uvm_pmr_isfree(struct vm_page *pg); #endif +#ifndef SMALL_KERNEL +void uvm_pmr_zero_everything(void); +int uvm_pmr_alloc_pig(paddr_t*, psize_t*); +#endif /* SMALL_KERNEL */ + #endif /* _UVM_UVM_PMEMRANGE_H_ */ |