summaryrefslogtreecommitdiffstats
path: root/sys/uvm/uvm_km.c
diff options
context:
space:
mode:
authorart <art@openbsd.org>2007-08-03 22:49:07 +0000
committerart <art@openbsd.org>2007-08-03 22:49:07 +0000
commite252743ab145fa6bb396a4eb8df1bc55472b7238 (patch)
tree201f97263c7c5618a43e1911dc89c95b6a68b378 /sys/uvm/uvm_km.c
parentwhen not dealing with floats, always multiply before dividing; from Przemyslaw Nowaczyk (diff)
downloadwireguard-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.c18
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().