summaryrefslogtreecommitdiffstats
path: root/sys/uvm/uvm_pmemrange.c
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 /sys/uvm/uvm_pmemrange.c
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@
Diffstat (limited to 'sys/uvm/uvm_pmemrange.c')
-rw-r--r--sys/uvm/uvm_pmemrange.c94
1 files changed, 93 insertions, 1 deletions
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 */