summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorAriane van der Steldt <ariane@cvs.openbsd.org>2011-06-22 00:16:48 +0000
committerAriane van der Steldt <ariane@cvs.openbsd.org>2011-06-22 00:16:48 +0000
commit5d5e214bb3fc042864e46fc7ded36e4e82ac98c0 (patch)
treee938f112f90ae1821917b329ea545ed0c8d03003 /sys/uvm
parent8fb4ca1998bfd5c39a15e6fe5493ba6727c8c9f3 (diff)
Validate pmemrange result, enabling early catching of bugs in the code.
ok beck@
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_pmemrange.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c
index 332326c25f1..714ae3c481b 100644
--- a/sys/uvm/uvm_pmemrange.c
+++ b/sys/uvm/uvm_pmemrange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pmemrange.c,v 1.24 2011/05/30 21:25:08 oga Exp $ */
+/* $OpenBSD: uvm_pmemrange.c,v 1.25 2011/06/22 00:16:47 ariane Exp $ */
/*
* Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl>
@@ -747,6 +747,9 @@ uvm_pmr_getpages(psize_t count, paddr_t start, paddr_t end, paddr_t align,
int memtype; /* Requested memtype. */
int memtype_init; /* Best memtype. */
int desperate; /* True if allocation failed. */
+#ifdef DIAGNOSTIC
+ struct vm_page *diag_prev; /* Used during validation. */
+#endif /* DIAGNOSTIC */
/*
* Validate arguments.
@@ -1049,6 +1052,11 @@ out:
uvm_unlock_fpageq();
/* Update statistics and zero pages if UVM_PLA_ZERO. */
+#ifdef DIAGNOSTIC
+ fnsegs = 0;
+ fcount = 0;
+ diag_prev = NULL;
+#endif /* DIAGNOSTIC */
TAILQ_FOREACH(found, result, pageq) {
atomic_clearbits_int(&found->pg_flags,
PG_PMAP0|PG_PMAP1|PG_PMAP2|PG_PMAP3);
@@ -1075,7 +1083,37 @@ out:
*/
KDASSERT(start == 0 || atop(VM_PAGE_TO_PHYS(found)) >= start);
KDASSERT(end == 0 || atop(VM_PAGE_TO_PHYS(found)) < end);
+
+#ifdef DIAGNOSTIC
+ /*
+ * Update fcount (# found pages) and
+ * fnsegs (# found segments) counters.
+ */
+ if (diag_prev == NULL ||
+ /* new segment if it contains a hole */
+ atop(VM_PAGE_TO_PHYS(diag_prev)) + 1 !=
+ atop(VM_PAGE_TO_PHYS(found)) ||
+ /* new segment if it crosses boundary */
+ (atop(VM_PAGE_TO_PHYS(diag_prev)) & ~(boundary - 1)) !=
+ (atop(VM_PAGE_TO_PHYS(found)) & ~(boundary - 1)))
+ fnsegs++;
+ fcount++;
+
+ diag_prev = found;
+#endif /* DIAGNOSTIC */
+ }
+
+#ifdef DIAGNOSTIC
+ /*
+ * Panic on algorithm failure.
+ */
+ if (fcount != count || fnsegs > maxseg) {
+ panic("pmemrange allocation error: "
+ "allocated %ld pages in %d segments, "
+ "but request was %ld pages in %d segments",
+ fcount, fnsegs, count, maxseg);
}
+#endif /* DIAGNOSTIC */
return 0;
}