diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2009-02-08 20:39:17 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2009-02-08 20:39:17 +0000 |
commit | 897d81a0202f3b068edfd20736cb55137bc88a12 (patch) | |
tree | 090d271c805930a672a18b2da7d0cd0774d02586 /sys/vm/vm_unix.c | |
parent | e53fa61bf2819349d66b210c5dd217379aea2a20 (diff) |
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
Notes
Notes:
svn path=/head/; revision=188334
Diffstat (limited to 'sys/vm/vm_unix.c')
-rw-r--r-- | sys/vm/vm_unix.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c index cd98be975e34..80921023450f 100644 --- a/sys/vm/vm_unix.c +++ b/sys/vm/vm_unix.c @@ -72,6 +72,7 @@ obreak(td, uap) struct obreak_args *uap; { struct vmspace *vm = td->td_proc->p_vmspace; + vm_map_entry_t freelist; vm_offset_t new, old, base; rlim_t datalim, vmemlim; int rv; @@ -85,6 +86,7 @@ obreak(td, uap) do_map_wirefuture = FALSE; new = round_page((vm_offset_t)uap->nsize); + freelist = NULL; vm_map_lock(&vm->vm_map); base = round_page((vm_offset_t) vm->vm_daddr); @@ -138,7 +140,7 @@ obreak(td, uap) do_map_wirefuture = TRUE; } } else if (new < old) { - rv = vm_map_delete(&vm->vm_map, new, old); + rv = vm_map_delete(&vm->vm_map, new, old, &freelist); if (rv != KERN_SUCCESS) { error = ENOMEM; goto done; @@ -147,6 +149,7 @@ obreak(td, uap) } done: vm_map_unlock(&vm->vm_map); + vm_map_entry_free_freelist(&vm->vm_map, freelist); if (do_map_wirefuture) (void) vm_map_wire(&vm->vm_map, old, new, |