summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthib <thib@openbsd.org>2010-07-02 01:13:59 +0000
committerthib <thib@openbsd.org>2010-07-02 01:13:59 +0000
commit28cfa0a38b5b7c07568f1160746fdb809d4e3dd2 (patch)
treee125a45992ea65cb4208e8318d07b3d57c9de564
parentPlug a memory leak where each update leaked one page. (diff)
downloadwireguard-openbsd-28cfa0a38b5b7c07568f1160746fdb809d4e3dd2.tar.xz
wireguard-openbsd-28cfa0a38b5b7c07568f1160746fdb809d4e3dd2.zip
Drop the uvm_km_pages.mtx mutex in uvm_km_putpage before we free va's,
as calls to uvm_km_free_wakup can end up in uvm_mapent_alloc which tries to grab this mutex. ok tedu@
-rw-r--r--sys/uvm/uvm_km.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c
index 52baf28ed14..b0028461e19 100644
--- a/sys/uvm/uvm_km.c
+++ b/sys/uvm/uvm_km.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_km.c,v 1.80 2010/06/29 20:39:27 thib Exp $ */
+/* $OpenBSD: uvm_km.c,v 1.81 2010/07/02 01:13:59 thib Exp $ */
/* $NetBSD: uvm_km.c,v 1.42 2001/01/14 02:10:01 thorpej Exp $ */
/*
@@ -866,6 +866,7 @@ uvm_km_putpage(void *v)
#ifdef __HAVE_PMAP_DIRECT
pg = pmap_unmap_direct(va);
#else /* !__HAVE_PMAP_DIRECT */
+ int freeva = 1;
paddr_t pa;
if (!pmap_extract(pmap_kernel(), va, &pa))
panic("lost pa");
@@ -877,11 +878,14 @@ uvm_km_putpage(void *v)
pmap_update(kernel_map->pmap);
mtx_enter(&uvm_km_pages.mtx);
- if (uvm_km_pages.free < uvm_km_pages.hiwat)
+ if (uvm_km_pages.free < uvm_km_pages.hiwat) {
uvm_km_pages.page[uvm_km_pages.free++] = va;
- else
- uvm_km_free_wakeup(kernel_map, va, PAGE_SIZE);
+ freeva = 0;
+ }
mtx_leave(&uvm_km_pages.mtx);
+
+ if (freeva)
+ uvm_km_free_wakeup(kernel_map, va, PAGE_SIZE);
#endif /* !__HAVE_PMAP_DIRECT */
uvm_pagefree(pg);