diff options
author | 2019-05-09 20:36:44 +0000 | |
---|---|---|
committer | 2019-05-09 20:36:44 +0000 | |
commit | d4c6c9b57a2886f149c0c3fc366ab553f5c7721a (patch) | |
tree | a2900691486856d802afbe1fcee40c1f314fc924 | |
parent | Unlock adjfreq(2), adjtime(2), clock_settime(2), and settimeofday(2). (diff) | |
download | wireguard-openbsd-d4c6c9b57a2886f149c0c3fc366ab553f5c7721a.tar.xz wireguard-openbsd-d4c6c9b57a2886f149c0c3fc366ab553f5c7721a.zip |
Ensure that pagedaemon wakeups as a result of failed UVM_PLA_NOWAIT
allocations will recover some memory from the dma_constraint range.
The allocation still fails, the intent is to ensure that the
pagedaemon will free some memory to possibly allow a subsequent
allocation to succeed.
This also adds a UVM_PLA_NOWAKE flag to allow special cases in the
buffer cache to not wake up the pagedaemon until they want to.
ok kettenis@
-rw-r--r-- | sys/kern/vfs_biomem.c | 6 | ||||
-rw-r--r-- | sys/uvm/uvm_extern.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_pdaemon.c | 30 | ||||
-rw-r--r-- | sys/uvm/uvm_pmemrange.c | 17 |
4 files changed, 45 insertions, 11 deletions
diff --git a/sys/kern/vfs_biomem.c b/sys/kern/vfs_biomem.c index 0f761c976c2..8bdd583fe58 100644 --- a/sys/kern/vfs_biomem.c +++ b/sys/kern/vfs_biomem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_biomem.c,v 1.40 2019/05/08 12:40:57 beck Exp $ */ +/* $OpenBSD: vfs_biomem.c,v 1.41 2019/05/09 20:36:44 beck Exp $ */ /* * Copyright (c) 2007 Artur Grabowski <art@openbsd.org> @@ -288,7 +288,7 @@ buf_alloc_pages(struct buf *bp, vsize_t size) */ do { i = uvm_pagealloc_multi(buf_object, offs, size, - UVM_PLA_NOWAIT); + UVM_PLA_NOWAIT | UVM_PLA_NOWAKE); if (i == 0) break; } while (bufbackoff(&dma_constraint, size) == 0); @@ -359,7 +359,7 @@ buf_realloc_pages(struct buf *bp, struct uvm_constraint_range *where, do { r = uvm_pagerealloc_multi(bp->b_pobj, bp->b_poffs, - bp->b_bufsize, UVM_PLA_NOWAIT, where); + bp->b_bufsize, UVM_PLA_NOWAIT | UVM_PLA_NOWAKE, where); if (r == 0) break; } while ((bufbackoff(where, atop(bp->b_bufsize)) == 0)); diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 24ddcd98ccd..12dc1f7b32f 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_extern.h,v 1.145 2019/03/01 01:46:18 cheloha Exp $ */ +/* $OpenBSD: uvm_extern.h,v 1.146 2019/05/09 20:36:44 beck Exp $ */ /* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */ /* @@ -151,6 +151,7 @@ typedef int vm_prot_t; #define UVM_PLA_ZERO 0x0004 /* zero all pages before returning */ #define UVM_PLA_TRYCONTIG 0x0008 /* try to allocate contig physmem */ #define UVM_PLA_FAILOK 0x0010 /* caller can handle failure */ +#define UVM_PLA_NOWAKE 0x0020 /* don't wake the page daemon on failure */ /* * lockflags that control the locking behavior of various functions. diff --git a/sys/uvm/uvm_pdaemon.c b/sys/uvm/uvm_pdaemon.c index c0368f66815..1c3c38fd5ea 100644 --- a/sys/uvm/uvm_pdaemon.c +++ b/sys/uvm/uvm_pdaemon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pdaemon.c,v 1.79 2018/01/18 18:08:51 bluhm Exp $ */ +/* $OpenBSD: uvm_pdaemon.c,v 1.80 2019/05/09 20:36:44 beck Exp $ */ /* $NetBSD: uvm_pdaemon.c,v 1.23 2000/08/20 10:24:14 bjh21 Exp $ */ /* @@ -186,6 +186,13 @@ uvmpd_tune(void) } /* + * Indicate to the page daemon that a nowait call failed and it should + * recover at least some memory in the most restricted region (assumed + * to be dma_constraint). + */ +volatile int uvm_nowait_failed; + +/* * uvm_pageout: the main loop for the pagedaemon */ void @@ -205,12 +212,17 @@ uvm_pageout(void *arg) uvm_unlock_pageq(); for (;;) { + int nowaitfailed = 0; long size; work_done = 0; /* No work done this iteration. */ uvm_lock_fpageq(); + if (uvm_nowait_failed) { + nowaitfailed = 1; + uvm_nowait_failed = 0; + } - if (TAILQ_EMPTY(&uvm.pmr_control.allocs)) { + if (!nowaitfailed && TAILQ_EMPTY(&uvm.pmr_control.allocs)) { msleep(&uvm.pagedaemon, &uvm.fpageqlock, PVM, "pgdaemon", 0); uvmexp.pdwoke++; @@ -219,8 +231,16 @@ uvm_pageout(void *arg) if ((pma = TAILQ_FIRST(&uvm.pmr_control.allocs)) != NULL) { pma->pm_flags |= UVM_PMA_BUSY; constraint = pma->pm_constraint; - } else - constraint = no_constraint; + } else { + if (nowaitfailed) { + /* + * XXX realisticly, this is what our + * nowait callers probably care about + */ + constraint = dma_constraint; + } else + constraint = no_constraint; + } uvm_unlock_fpageq(); @@ -243,6 +263,8 @@ uvm_pageout(void *arg) if (uvmexp.free - BUFPAGES_DEFICIT < uvmexp.freetarg) size += uvmexp.freetarg - (uvmexp.free - BUFPAGES_DEFICIT); + if (size == 0) + size = 16; /* XXX */ uvm_unlock_pageq(); (void) bufbackoff(&constraint, size * 2); uvm_lock_pageq(); diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c index dcddfe35a14..cd92c319650 100644 --- a/sys/uvm/uvm_pmemrange.c +++ b/sys/uvm/uvm_pmemrange.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pmemrange.c,v 1.53 2016/09/16 02:52:24 dlg Exp $ */ +/* $OpenBSD: uvm_pmemrange.c,v 1.54 2019/05/09 20:36:44 beck Exp $ */ /* * Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl> @@ -702,6 +702,13 @@ uvm_pmr_extract_range(struct uvm_pmemrange *pmr, struct vm_page *pg, } /* + * Indicate to the page daemon that a nowait call failed and it should + * recover at least some memory in the most restricted region (assumed + * to be dma_constraint). + */ +extern volatile int uvm_nowait_failed; + +/* * Acquire a number of pages. * * count: the number of pages returned @@ -1014,8 +1021,12 @@ fail: flags & UVM_PLA_FAILOK) == 0) goto retry; KASSERT(flags & UVM_PLA_FAILOK); - } else - wakeup(&uvm.pagedaemon); + } else { + if (!(flags & UVM_PLA_NOWAKE)) { + uvm_nowait_failed = 1; + wakeup(&uvm.pagedaemon); + } + } uvm_unlock_fpageq(); return ENOMEM; |