diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2013-02-07 17:38:13 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2013-02-07 17:38:13 +0000 |
commit | 8ace929406d6b0c172b9a852dd0daa8563ba8805 (patch) | |
tree | 7856b3d80e5f080e80a520103576499703a67778 /sys | |
parent | d5b300abf19b9f371d02d783d53140e17691c9fa (diff) |
Bring back reserve enforcement and page daemon wakeup into uvm_pglistalloc,
It was removed as this function was redone to use pmemrange in mid 2010
with the result that kernel malloc and other users of this function can
consume the page daemon reserve and run us out of memory.
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/uvm/uvm_page.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 6d44a95b6aa..7834b55db82 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.114 2011/07/08 00:10:59 tedu Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.115 2013/02/07 17:38:12 beck Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -792,13 +792,39 @@ int uvm_pglistalloc(psize_t size, paddr_t low, paddr_t high, paddr_t alignment, paddr_t boundary, struct pglist *rlist, int nsegs, int flags) { - KASSERT((alignment & (alignment - 1)) == 0); KASSERT((boundary & (boundary - 1)) == 0); KASSERT(!(flags & UVM_PLA_WAITOK) ^ !(flags & UVM_PLA_NOWAIT)); if (size == 0) return (EINVAL); + /* + * check to see if we need to generate some free pages waking + * the pagedaemon. + */ + if ((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freemin || + ((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freetarg && + (uvmexp.inactive + BUFPAGES_INACT) < uvmexp.inactarg)) + wakeup(&uvm.pagedaemon); + + /* + * XXX uvm_pglistalloc is currently only used for kernel + * objects. Unlike the checks in uvm_pagealloc, below, here + * we are always allowed to use the kernel reseve. However, we + * have to enforce the pagedaemon reserve here or allocations + * via this path could consume everything and we can't + * recover in the page daemon. + */ + again: + if ((uvmexp.free <= uvmexp.reserve_pagedaemon && + !((curproc == uvm.pagedaemon_proc) || + (curproc == syncerproc)))) { + if (UVM_PLA_WAITOK) { + uvm_wait("uvm_pglistalloc"); + goto again; + } + return (ENOMEM); + } if ((high & PAGE_MASK) != PAGE_MASK) { printf("uvm_pglistalloc: Upper boundary 0x%lx " |