summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbeck <beck@openbsd.org>2013-02-07 17:38:12 +0000
committerbeck <beck@openbsd.org>2013-02-07 17:38:12 +0000
commit328c377a64cc9268fdefd3facae3c7dad58a17c4 (patch)
treefca2f887d95f8282d9c2bde5d1e737e8a89b3f5d /sys
parentmake sure the page daemon considers BUFPAGES_INACT when deciding (diff)
downloadwireguard-openbsd-328c377a64cc9268fdefd3facae3c7dad58a17c4.tar.xz
wireguard-openbsd-328c377a64cc9268fdefd3facae3c7dad58a17c4.zip
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.c30
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 "