summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_pmemrange.c
diff options
context:
space:
mode:
authorThordur I. Bjornsson <thib@cvs.openbsd.org>2010-06-23 09:36:04 +0000
committerThordur I. Bjornsson <thib@cvs.openbsd.org>2010-06-23 09:36:04 +0000
commit568c3e3586a8b03d5177fb19e77b35519f81a86f (patch)
treebe1fd0d047f193c3b3b57b97d6bb884c4237963f /sys/uvm/uvm_pmemrange.c
parentf3fbfca1c4282fc4c7b4804c0a28e68508a66664 (diff)
Fix a bug in uvm_pmr_get1page() which could cause us to bounce
between an allocating process failing and waking up the pagedaemon and the pagedaemon (since everything was dandy). Rework the do ... while () logic searching for pages of a certain memtype in a pmr into a while () loop where we check if we've found enough pages and break out of the pmr and check the memtype inside the loop. This prevents us from doing an early return without enough pages for the caller even though more pages exist. comments and help from oga, style nit from miod. OK miod@, oga@
Diffstat (limited to 'sys/uvm/uvm_pmemrange.c')
-rw-r--r--sys/uvm/uvm_pmemrange.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c
index 5b2917e4343..54d3f6960d6 100644
--- a/sys/uvm/uvm_pmemrange.c
+++ b/sys/uvm/uvm_pmemrange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pmemrange.c,v 1.13 2010/06/10 08:48:36 thib Exp $ */
+/* $OpenBSD: uvm_pmemrange.c,v 1.14 2010/06/23 09:36:03 thib Exp $ */
/*
* Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl>
@@ -1638,8 +1638,11 @@ uvm_pmr_get1page(psize_t count, int memtype_init, struct pglist *result,
int memtype;
fcount = 0;
- for (pmr = TAILQ_FIRST(&uvm.pmr_control.use);
- pmr != NULL && fcount != count; pmr = TAILQ_NEXT(pmr, pmr_use)) {
+ TAILQ_FOREACH(pmr, &uvm.pmr_control.use, pmr_use) {
+ /* We're done. */
+ if (fcount == count)
+ break;
+
/* Outside requested range. */
if (!(start == 0 && end == 0) &&
!PMR_INTERSECTS_WITH(pmr->low, pmr->high, start, end))
@@ -1649,11 +1652,9 @@ uvm_pmr_get1page(psize_t count, int memtype_init, struct pglist *result,
if (pmr->nsegs == 0)
continue;
- /*
- * Loop over all memtypes, starting at memtype_init.
- */
+ /* Loop over all memtypes, starting at memtype_init. */
memtype = memtype_init;
- do {
+ while (fcount != count) {
found = TAILQ_FIRST(&pmr->single[memtype]);
/*
* If found is outside the range, walk the list
@@ -1751,8 +1752,10 @@ uvm_pmr_get1page(psize_t count, int memtype_init, struct pglist *result,
memtype += 1;
if (memtype == UVM_PMR_MEMTYPE_MAX)
memtype = 0;
+ if (memtype == memtype_init)
+ break;
}
- } while (memtype != memtype_init && fcount != count);
+ }
}
/*