diff options
author | 2010-07-24 15:40:39 +0000 | |
---|---|---|
committer | 2010-07-24 15:40:39 +0000 | |
commit | cf70c43b1a1e4e3bd82336e4b0f233c4b81aa264 (patch) | |
tree | 10e1585064efe7578ac3c6f87a893eb973f43794 | |
parent | sync (diff) | |
download | wireguard-openbsd-cf70c43b1a1e4e3bd82336e4b0f233c4b81aa264.tar.xz wireguard-openbsd-cf70c43b1a1e4e3bd82336e4b0f233c4b81aa264.zip |
Don't sleep while holding the uvm_psel_lck mutex. Should fix "locking against
myself" panics that some people have seen over the last year-and-a-half.
Cherry picked from a more complex (and therefore scarier) diff from oga@.
ok tedu@, oga@
-rw-r--r-- | sys/uvm/uvm_pager.c | 32 |
1 files changed, 9 insertions, 23 deletions
diff --git a/sys/uvm/uvm_pager.c b/sys/uvm/uvm_pager.c index 2e307afedcd..f634caecc96 100644 --- a/sys/uvm/uvm_pager.c +++ b/sys/uvm/uvm_pager.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pager.c,v 1.56 2010/06/27 20:53:31 oga Exp $ */ +/* $OpenBSD: uvm_pager.c,v 1.57 2010/07/24 15:40:39 kettenis Exp $ */ /* $NetBSD: uvm_pager.c,v 1.36 2000/11/27 18:26:41 chs Exp $ */ /* @@ -88,7 +88,6 @@ struct uvm_pseg psegs[PSEG_NUMSEGS]; #define UVM_PSEG_INUSE(pseg,id) (((pseg)->use & (1 << (id))) != 0) void uvm_pseg_init(struct uvm_pseg *); -void uvm_pseg_destroy(struct uvm_pseg *); vaddr_t uvm_pseg_get(int); void uvm_pseg_release(vaddr_t); @@ -142,25 +141,6 @@ uvm_pseg_init(struct uvm_pseg *pseg) } /* - * Destroy a uvm_pseg. - * - * Never fails. - * - * Requires that seg != &psegs[0] - * - * Caller locks uvm_pseg_lck. - */ -void -uvm_pseg_destroy(struct uvm_pseg *pseg) -{ - KASSERT(pseg != &psegs[0]); - KASSERT(pseg->start != 0); - KASSERT(pseg->use == 0); - uvm_km_free(kernel_map, pseg->start, MAX_PAGER_SEGS * MAXBSIZE); - pseg->start = 0; -} - -/* * Acquire a pager map segment. * * Returns a vaddr for paging. 0 on failure. @@ -225,6 +205,7 @@ uvm_pseg_release(vaddr_t segaddr) { int id; struct uvm_pseg *pseg; + vaddr_t va = 0; for (pseg = &psegs[0]; pseg != &psegs[PSEG_NUMSEGS]; pseg++) { if (pseg->start <= segaddr && @@ -246,10 +227,15 @@ uvm_pseg_release(vaddr_t segaddr) pseg->use &= ~(1 << id); wakeup(&psegs); - if (pseg != &psegs[0] && UVM_PSEG_EMPTY(pseg)) - uvm_pseg_destroy(pseg); + if (pseg != &psegs[0] && UVM_PSEG_EMPTY(pseg)) { + va = pseg->start; + pseg->start = 0; + } mtx_leave(&uvm_pseg_lck); + + if (va) + uvm_km_free(kernel_map, va, MAX_PAGER_SEGS * MAXBSIZE); } /* |