diff options
author | 2007-08-03 22:49:07 +0000 | |
---|---|---|
committer | 2007-08-03 22:49:07 +0000 | |
commit | e252743ab145fa6bb396a4eb8df1bc55472b7238 (patch) | |
tree | 201f97263c7c5618a43e1911dc89c95b6a68b378 /sys/uvm/uvm_km.c | |
parent | when not dealing with floats, always multiply before dividing; from Przemyslaw Nowaczyk (diff) | |
download | wireguard-openbsd-e252743ab145fa6bb396a4eb8df1bc55472b7238.tar.xz wireguard-openbsd-e252743ab145fa6bb396a4eb8df1bc55472b7238.zip |
Don't let pagedaemon wait for pages here. We could trigger this easily
when we hit swap before actually fully populating the buffer cache which
would lead to deadlocks.
From pedro, tested by many, deraadt@ ok
Diffstat (limited to 'sys/uvm/uvm_km.c')
-rw-r--r-- | sys/uvm/uvm_km.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c index f854f418faf..02f0eb0aa4e 100644 --- a/sys/uvm/uvm_km.c +++ b/sys/uvm/uvm_km.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_km.c,v 1.63 2007/04/29 15:46:42 art Exp $ */ +/* $OpenBSD: uvm_km.c,v 1.64 2007/08/03 22:49:07 art Exp $ */ /* $NetBSD: uvm_km.c,v 1.42 2001/01/14 02:10:01 thorpej Exp $ */ /* @@ -534,10 +534,20 @@ uvm_km_alloc1(struct vm_map *map, vsize_t size, vsize_t align, boolean_t zeroit) } simple_unlock(&uvm.kernel_object->vmobjlock); if (__predict_false(pg == NULL)) { - uvm_wait("km_alloc1w"); /* wait for memory */ - continue; + if (curproc == uvm.pagedaemon_proc) { + /* + * It is unfeasible for the page daemon to + * sleep for memory, so free what we have + * allocated and fail. + */ + uvm_unmap(map, kva, loopva - kva); + return (NULL); + } else { + uvm_wait("km_alloc1w"); /* wait for memory */ + continue; + } } - + /* * map it in; note we're never called with an intrsafe * object, so we always use regular old pmap_enter(). |