diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-07-24 15:40:40 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-07-24 15:40:40 +0000 |
commit | c40dee760bf4df2778d8083fdcc66acdbeab3a5d (patch) | |
tree | 69dd5c906b8d7b2701d20041487ea97dc99e7ca4 /sys/uvm | |
parent | d26d482cf7ff4722439913763a5d968c2bde63ca (diff) |
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@
Diffstat (limited to 'sys/uvm')
-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); } /* |