diff options
author | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2010-06-23 09:36:04 +0000 |
---|---|---|
committer | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2010-06-23 09:36:04 +0000 |
commit | 568c3e3586a8b03d5177fb19e77b35519f81a86f (patch) | |
tree | be1fd0d047f193c3b3b57b97d6bb884c4237963f | |
parent | f3fbfca1c4282fc4c7b4804c0a28e68508a66664 (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@
-rw-r--r-- | sys/uvm/uvm_pmemrange.c | 19 |
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); + } } /* |