Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_map.c
Show First 20 Lines • Show All 3,418 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
struct vmspace * | struct vmspace * | ||||
vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge) | vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge) | ||||
{ | { | ||||
struct vmspace *vm2; | struct vmspace *vm2; | ||||
vm_map_t new_map, old_map; | vm_map_t new_map, old_map; | ||||
vm_map_entry_t new_entry, old_entry; | vm_map_entry_t new_entry, old_entry; | ||||
vm_object_t object; | vm_object_t object; | ||||
int locked; | int error, locked; | ||||
vm_inherit_t inh; | vm_inherit_t inh; | ||||
old_map = &vm1->vm_map; | old_map = &vm1->vm_map; | ||||
/* Copy immutable fields of vm1 to vm2. */ | /* Copy immutable fields of vm1 to vm2. */ | ||||
vm2 = vmspace_alloc(vm_map_min(old_map), vm_map_max(old_map), | vm2 = vmspace_alloc(vm_map_min(old_map), vm_map_max(old_map), | ||||
pmap_pinit); | pmap_pinit); | ||||
if (vm2 == NULL) | if (vm2 == NULL) | ||||
return (NULL); | return (NULL); | ||||
vm2->vm_taddr = vm1->vm_taddr; | vm2->vm_taddr = vm1->vm_taddr; | ||||
vm2->vm_daddr = vm1->vm_daddr; | vm2->vm_daddr = vm1->vm_daddr; | ||||
vm2->vm_maxsaddr = vm1->vm_maxsaddr; | vm2->vm_maxsaddr = vm1->vm_maxsaddr; | ||||
vm_map_lock(old_map); | vm_map_lock(old_map); | ||||
if (old_map->busy) | if (old_map->busy) | ||||
vm_map_wait_busy(old_map); | vm_map_wait_busy(old_map); | ||||
new_map = &vm2->vm_map; | new_map = &vm2->vm_map; | ||||
locked = vm_map_trylock(new_map); /* trylock to silence WITNESS */ | locked = vm_map_trylock(new_map); /* trylock to silence WITNESS */ | ||||
KASSERT(locked, ("vmspace_fork: lock failed")); | KASSERT(locked, ("vmspace_fork: lock failed")); | ||||
error = pmap_vmspace_copy(new_map->pmap, old_map->pmap); | |||||
if (error != 0) { | |||||
sx_xunlock(&old_map->lock); | |||||
markj: Why not use vm_map_unlock()? | |||||
Done Inline ActionsFor the same reason why plain sx_xunlock() is used at the end of the function, see comment (we cannot process deferred free entries until both maps are unlocked). That said, the code should call the processing function even if formally. kib: For the same reason why plain sx_xunlock() is used at the end of the function, see comment (we… | |||||
sx_xunlock(&new_map->lock); | |||||
vmspace_free(vm2); | |||||
return (NULL); | |||||
} | |||||
old_entry = old_map->header.next; | old_entry = old_map->header.next; | ||||
while (old_entry != &old_map->header) { | while (old_entry != &old_map->header) { | ||||
if (old_entry->eflags & MAP_ENTRY_IS_SUB_MAP) | if (old_entry->eflags & MAP_ENTRY_IS_SUB_MAP) | ||||
panic("vm_map_fork: encountered a submap"); | panic("vm_map_fork: encountered a submap"); | ||||
inh = old_entry->inheritance; | inh = old_entry->inheritance; | ||||
▲ Show 20 Lines • Show All 997 Lines • Show Last 20 Lines |
Why not use vm_map_unlock()?