summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorariane <ariane@openbsd.org>2011-04-03 22:07:37 +0000
committerariane <ariane@openbsd.org>2011-04-03 22:07:37 +0000
commit205bb46da6adb871d9864633a3fa3527e6063831 (patch)
treeef3ff8925c818d5dac7d66e5cfc1707744455a53
parentCall setlocale() to avoid display glitches in UTF-8 locales. (diff)
downloadwireguard-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.c14
-rw-r--r--sys/sys/pool.h3
-rw-r--r--sys/uvm/uvm_pmemrange.c94
-rw-r--r--sys/uvm/uvm_pmemrange.h7
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_ */