diff options
author | Ariane van der Steldt <ariane@cvs.openbsd.org> | 2011-06-22 00:16:48 +0000 |
---|---|---|
committer | Ariane van der Steldt <ariane@cvs.openbsd.org> | 2011-06-22 00:16:48 +0000 |
commit | 5d5e214bb3fc042864e46fc7ded36e4e82ac98c0 (patch) | |
tree | e938f112f90ae1821917b329ea545ed0c8d03003 /sys/uvm | |
parent | 8fb4ca1998bfd5c39a15e6fe5493ba6727c8c9f3 (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.c | 40 |
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; } |