diff options
author | kib <kib@FreeBSD.org> | 2009-02-08 20:39:17 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-02-08 20:39:17 +0000 |
commit | ae7c4cfa1196d4f42be0f573c827a5dd2d385af9 (patch) | |
tree | 090d271c805930a672a18b2da7d0cd0774d02586 /sys/vm/vm_kern.c | |
parent | 9a341e28ebd8cb82b35c8eeb849a7607597d399e (diff) | |
download | FreeBSD-src-ae7c4cfa1196d4f42be0f573c827a5dd2d385af9.zip FreeBSD-src-ae7c4cfa1196d4f42be0f573c827a5dd2d385af9.tar.gz |
Do not call vm_object_deallocate() from vm_map_delete(), because we
hold the map lock there, and might need the vnode lock for OBJT_VNODE
objects. Postpone object deallocation until caller of vm_map_delete()
drops the map lock. Link the map entries to be freed into the freelist,
that is released by the new helper function vm_map_entry_free_freelist().
Reviewed by: tegge, alc
Tested by: pho
Diffstat (limited to 'sys/vm/vm_kern.c')
-rw-r--r-- | sys/vm/vm_kern.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 9a1ac63..b438058 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -271,7 +271,7 @@ kmem_malloc(map, size, flags) int flags; { vm_offset_t offset, i; - vm_map_entry_t entry; + vm_map_entry_t entry, freelist; vm_offset_t addr; vm_page_t m; int pflags; @@ -355,8 +355,10 @@ retry: vm_page_unlock_queues(); } VM_OBJECT_UNLOCK(kmem_object); - vm_map_delete(map, addr, addr + size); + freelist = NULL; + vm_map_delete(map, addr, addr + size, &freelist); vm_map_unlock(map); + vm_map_entry_free_freelist(map, freelist); return (0); } if (flags & M_ZERO && (m->flags & PG_ZERO) == 0) @@ -455,14 +457,18 @@ kmem_free_wakeup(map, addr, size) vm_offset_t addr; vm_size_t size; { + vm_map_entry_t freelist; + freelist = NULL; vm_map_lock(map); - (void) vm_map_delete(map, trunc_page(addr), round_page(addr + size)); + (void) vm_map_delete(map, trunc_page(addr), round_page(addr + size), + &freelist); if (map->needs_wakeup) { map->needs_wakeup = FALSE; vm_map_wakeup(map); } vm_map_unlock(map); + vm_map_entry_free_freelist(map, freelist); } /* |