diff options
author | 2015-12-16 14:22:21 +0000 | |
---|---|---|
committer | 2015-12-16 14:22:21 +0000 | |
commit | 128f03b1c7aacd60585040470aeb48fa35e8cad0 (patch) | |
tree | 121cba3a5ee7e4678176a91f936262c089c4f30a | |
parent | Use __progname instead of hand-rolled parsing of argv[0]. (diff) | |
download | wireguard-openbsd-128f03b1c7aacd60585040470aeb48fa35e8cad0.tar.xz wireguard-openbsd-128f03b1c7aacd60585040470aeb48fa35e8cad0.zip |
Avoid grabbing the kernel lock in uvm_unmap() if we have an interrupt-safe
map. This removes the (hopefully) last case in which pool_put() might try
to grab the kernel lock for interrupt-safe pools. Note that pools that are
created with the PR_WAITOK flag will still grab the kernel lock.
ok mpi@, tedu@
-rw-r--r-- | sys/uvm/uvm_map.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c index 24d9168355e..463c7498c99 100644 --- a/sys/uvm/uvm_map.c +++ b/sys/uvm/uvm_map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_map.c,v 1.204 2015/11/14 14:53:14 miod Exp $ */ +/* $OpenBSD: uvm_map.c,v 1.205 2015/12/16 14:22:21 kettenis Exp $ */ /* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */ /* @@ -119,6 +119,7 @@ struct vm_map_entry *uvm_mapent_alloc(struct vm_map*, int); void uvm_mapent_free(struct vm_map_entry*); void uvm_unmap_kill_entry(struct vm_map*, struct vm_map_entry*); +void uvm_unmap_detach_intrsafe(struct uvm_map_deadq *); void uvm_mapent_mkfree(struct vm_map*, struct vm_map_entry*, struct vm_map_entry**, struct uvm_map_deadq*, boolean_t); @@ -1554,6 +1555,20 @@ uvm_unmap_detach(struct uvm_map_deadq *deadq, int flags) KERNEL_UNLOCK(); } +void +uvm_unmap_detach_intrsafe(struct uvm_map_deadq *deadq) +{ + struct vm_map_entry *entry; + + while ((entry = TAILQ_FIRST(deadq)) != NULL) { + KASSERT(entry->aref.ar_amap == NULL); + KASSERT(!UVM_ET_ISSUBMAP(entry)); + KASSERT(!UVM_ET_ISOBJ(entry)); + TAILQ_REMOVE(deadq, entry, dfree.deadq); + uvm_mapent_free(entry); + } +} + /* * Create and insert new entry. * @@ -1791,7 +1806,10 @@ uvm_unmap(struct vm_map *map, vaddr_t start, vaddr_t end) uvm_unmap_remove(map, start, end, &dead, FALSE, TRUE); vm_map_unlock(map); - uvm_unmap_detach(&dead, 0); + if (map->flags & VM_MAP_INTRSAFE) + uvm_unmap_detach_intrsafe(&dead); + else + uvm_unmap_detach(&dead, 0); } /* |