From 8ace929406d6b0c172b9a852dd0daa8563ba8805 Mon Sep 17 00:00:00 2001 From: Bob Beck Date: Thu, 7 Feb 2013 17:38:13 +0000 Subject: 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@ --- sys/uvm/uvm_page.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'sys') 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 " -- cgit v1.2.3