Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_map.c
Show First 20 Lines • Show All 569 Lines • ▼ Show 20 Lines | vm_map_process_deferred(void) | ||||
vm_map_entry_t entry, next; | vm_map_entry_t entry, next; | ||||
vm_object_t object; | vm_object_t object; | ||||
td = curthread; | td = curthread; | ||||
entry = td->td_map_def_user; | entry = td->td_map_def_user; | ||||
td->td_map_def_user = NULL; | td->td_map_def_user = NULL; | ||||
while (entry != NULL) { | while (entry != NULL) { | ||||
next = entry->next; | next = entry->next; | ||||
MPASS((entry->eflags & (MAP_ENTRY_VN_WRITECNT | | MPASS((entry->eflags & (MAP_ENTRY_WRITECNT | | ||||
MAP_ENTRY_VN_EXEC)) != (MAP_ENTRY_VN_WRITECNT | | MAP_ENTRY_VN_EXEC)) != (MAP_ENTRY_WRITECNT | | ||||
MAP_ENTRY_VN_EXEC)); | MAP_ENTRY_VN_EXEC)); | ||||
if ((entry->eflags & MAP_ENTRY_VN_WRITECNT) != 0) { | if ((entry->eflags & MAP_ENTRY_WRITECNT) != 0) { | ||||
/* | /* | ||||
* Decrement the object's writemappings and | * Decrement the object's writemappings and | ||||
* possibly the vnode's v_writecount. | * possibly the vnode's v_writecount. | ||||
*/ | */ | ||||
KASSERT((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0, | KASSERT((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0, | ||||
("Submap with writecount")); | ("Submap with writecount")); | ||||
object = entry->object.vm_object; | object = entry->object.vm_object; | ||||
KASSERT(object != NULL, ("No object for writecount")); | KASSERT(object != NULL, ("No object for writecount")); | ||||
vnode_pager_release_writecount(object, entry->start, | vm_pager_release_writecount(object, entry->start, | ||||
entry->end); | entry->end); | ||||
} | } | ||||
vm_map_entry_set_vnode_text(entry, false); | vm_map_entry_set_vnode_text(entry, false); | ||||
vm_map_entry_deallocate(entry, FALSE); | vm_map_entry_deallocate(entry, FALSE); | ||||
entry = next; | entry = next; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 877 Lines • ▼ Show 20 Lines | vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, | ||||
if (cow & MAP_DISABLE_SYNCER) | if (cow & MAP_DISABLE_SYNCER) | ||||
protoeflags |= MAP_ENTRY_NOSYNC; | protoeflags |= MAP_ENTRY_NOSYNC; | ||||
if (cow & MAP_DISABLE_COREDUMP) | if (cow & MAP_DISABLE_COREDUMP) | ||||
protoeflags |= MAP_ENTRY_NOCOREDUMP; | protoeflags |= MAP_ENTRY_NOCOREDUMP; | ||||
if (cow & MAP_STACK_GROWS_DOWN) | if (cow & MAP_STACK_GROWS_DOWN) | ||||
protoeflags |= MAP_ENTRY_GROWS_DOWN; | protoeflags |= MAP_ENTRY_GROWS_DOWN; | ||||
if (cow & MAP_STACK_GROWS_UP) | if (cow & MAP_STACK_GROWS_UP) | ||||
protoeflags |= MAP_ENTRY_GROWS_UP; | protoeflags |= MAP_ENTRY_GROWS_UP; | ||||
if (cow & MAP_VN_WRITECOUNT) | if (cow & MAP_WRITECOUNT) | ||||
protoeflags |= MAP_ENTRY_VN_WRITECNT; | protoeflags |= MAP_ENTRY_WRITECNT; | ||||
if (cow & MAP_VN_EXEC) | if (cow & MAP_VN_EXEC) | ||||
protoeflags |= MAP_ENTRY_VN_EXEC; | protoeflags |= MAP_ENTRY_VN_EXEC; | ||||
if ((cow & MAP_CREATE_GUARD) != 0) | if ((cow & MAP_CREATE_GUARD) != 0) | ||||
protoeflags |= MAP_ENTRY_GUARD; | protoeflags |= MAP_ENTRY_GUARD; | ||||
if ((cow & MAP_CREATE_STACK_GAP_DN) != 0) | if ((cow & MAP_CREATE_STACK_GAP_DN) != 0) | ||||
protoeflags |= MAP_ENTRY_STACK_GAP_DN; | protoeflags |= MAP_ENTRY_STACK_GAP_DN; | ||||
if ((cow & MAP_CREATE_STACK_GAP_UP) != 0) | if ((cow & MAP_CREATE_STACK_GAP_UP) != 0) | ||||
protoeflags |= MAP_ENTRY_STACK_GAP_UP; | protoeflags |= MAP_ENTRY_STACK_GAP_UP; | ||||
▲ Show 20 Lines • Show All 712 Lines • ▼ Show 20 Lines | _vm_map_clip_start(vm_map_t map, vm_map_entry_t entry, vm_offset_t start) | ||||
vm_map_entry_link(map, new_entry); | vm_map_entry_link(map, new_entry); | ||||
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { | if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { | ||||
vm_object_reference(new_entry->object.vm_object); | vm_object_reference(new_entry->object.vm_object); | ||||
vm_map_entry_set_vnode_text(new_entry, true); | vm_map_entry_set_vnode_text(new_entry, true); | ||||
/* | /* | ||||
* The object->un_pager.vnp.writemappings for the | * The object->un_pager.vnp.writemappings for the | ||||
* object of MAP_ENTRY_VN_WRITECNT type entry shall be | * object of MAP_ENTRY_WRITECNT type entry shall be | ||||
* kept as is here. The virtual pages are | * kept as is here. The virtual pages are | ||||
* re-distributed among the clipped entries, so the sum is | * re-distributed among the clipped entries, so the sum is | ||||
* left the same. | * left the same. | ||||
*/ | */ | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,555 Lines • ▼ Show 20 Lines | if ((src_object = src_entry->object.vm_object) != NULL) { | ||||
*fork_charge += size; | *fork_charge += size; | ||||
} | } | ||||
} | } | ||||
src_entry->eflags |= MAP_ENTRY_COW | | src_entry->eflags |= MAP_ENTRY_COW | | ||||
MAP_ENTRY_NEEDS_COPY; | MAP_ENTRY_NEEDS_COPY; | ||||
dst_entry->eflags |= MAP_ENTRY_COW | | dst_entry->eflags |= MAP_ENTRY_COW | | ||||
MAP_ENTRY_NEEDS_COPY; | MAP_ENTRY_NEEDS_COPY; | ||||
dst_entry->offset = src_entry->offset; | dst_entry->offset = src_entry->offset; | ||||
if (src_entry->eflags & MAP_ENTRY_VN_WRITECNT) { | if (src_entry->eflags & MAP_ENTRY_WRITECNT) { | ||||
/* | /* | ||||
* MAP_ENTRY_VN_WRITECNT cannot | * MAP_ENTRY_WRITECNT cannot | ||||
* indicate write reference from | * indicate write reference from | ||||
* src_entry, since the entry is | * src_entry, since the entry is | ||||
* marked as needs copy. Allocate a | * marked as needs copy. Allocate a | ||||
* fake entry that is used to | * fake entry that is used to | ||||
* decrement object->un_pager.vnp.writecount | * decrement object->un_pager writecount | ||||
* at the appropriate time. Attach | * at the appropriate time. Attach | ||||
* fake_entry to the deferred list. | * fake_entry to the deferred list. | ||||
*/ | */ | ||||
fake_entry = vm_map_entry_create(dst_map); | fake_entry = vm_map_entry_create(dst_map); | ||||
fake_entry->eflags = MAP_ENTRY_VN_WRITECNT; | fake_entry->eflags = MAP_ENTRY_WRITECNT; | ||||
src_entry->eflags &= ~MAP_ENTRY_VN_WRITECNT; | src_entry->eflags &= ~MAP_ENTRY_WRITECNT; | ||||
vm_object_reference(src_object); | vm_object_reference(src_object); | ||||
fake_entry->object.vm_object = src_object; | fake_entry->object.vm_object = src_object; | ||||
fake_entry->start = src_entry->start; | fake_entry->start = src_entry->start; | ||||
fake_entry->end = src_entry->end; | fake_entry->end = src_entry->end; | ||||
fake_entry->next = curthread->td_map_def_user; | fake_entry->next = curthread->td_map_def_user; | ||||
curthread->td_map_def_user = fake_entry; | curthread->td_map_def_user = fake_entry; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | case VM_INHERIT_SHARE: | ||||
} | } | ||||
/* | /* | ||||
* Assert the correct state of the vnode | * Assert the correct state of the vnode | ||||
* v_writecount while the object is locked, to | * v_writecount while the object is locked, to | ||||
* not relock it later for the assertion | * not relock it later for the assertion | ||||
* correctness. | * correctness. | ||||
*/ | */ | ||||
if (old_entry->eflags & MAP_ENTRY_VN_WRITECNT && | if (old_entry->eflags & MAP_ENTRY_WRITECNT && | ||||
object->type == OBJT_VNODE) { | object->type == OBJT_VNODE) { | ||||
KASSERT(((struct vnode *)object->handle)-> | KASSERT(((struct vnode *)object->handle)-> | ||||
v_writecount > 0, | v_writecount > 0, | ||||
("vmspace_fork: v_writecount %p", object)); | ("vmspace_fork: v_writecount %p", object)); | ||||
KASSERT(object->un_pager.vnp.writemappings > 0, | KASSERT(object->un_pager.vnp.writemappings > 0, | ||||
("vmspace_fork: vnp.writecount %p", | ("vmspace_fork: vnp.writecount %p", | ||||
object)); | object)); | ||||
} | } | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
/* | /* | ||||
* Clone the entry, referencing the shared object. | * Clone the entry, referencing the shared object. | ||||
*/ | */ | ||||
new_entry = vm_map_entry_create(new_map); | new_entry = vm_map_entry_create(new_map); | ||||
*new_entry = *old_entry; | *new_entry = *old_entry; | ||||
new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | | new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | | ||||
MAP_ENTRY_IN_TRANSITION); | MAP_ENTRY_IN_TRANSITION); | ||||
new_entry->wiring_thread = NULL; | new_entry->wiring_thread = NULL; | ||||
new_entry->wired_count = 0; | new_entry->wired_count = 0; | ||||
if (new_entry->eflags & MAP_ENTRY_VN_WRITECNT) { | if (new_entry->eflags & MAP_ENTRY_WRITECNT) { | ||||
vnode_pager_update_writecount(object, | vm_pager_update_writecount(object, | ||||
new_entry->start, new_entry->end); | new_entry->start, new_entry->end); | ||||
} | } | ||||
vm_map_entry_set_vnode_text(new_entry, true); | vm_map_entry_set_vnode_text(new_entry, true); | ||||
/* | /* | ||||
* Insert the entry into the new map -- we know we're | * Insert the entry into the new map -- we know we're | ||||
* inserting at the end of the new map. | * inserting at the end of the new map. | ||||
*/ | */ | ||||
Show All 14 Lines | case VM_INHERIT_COPY: | ||||
* Clone the entry and link into the map. | * Clone the entry and link into the map. | ||||
*/ | */ | ||||
new_entry = vm_map_entry_create(new_map); | new_entry = vm_map_entry_create(new_map); | ||||
*new_entry = *old_entry; | *new_entry = *old_entry; | ||||
/* | /* | ||||
* Copied entry is COW over the old object. | * Copied entry is COW over the old object. | ||||
*/ | */ | ||||
new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | | new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | | ||||
MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_VN_WRITECNT); | MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_WRITECNT); | ||||
new_entry->wiring_thread = NULL; | new_entry->wiring_thread = NULL; | ||||
new_entry->wired_count = 0; | new_entry->wired_count = 0; | ||||
new_entry->object.vm_object = NULL; | new_entry->object.vm_object = NULL; | ||||
new_entry->cred = NULL; | new_entry->cred = NULL; | ||||
vm_map_entry_link(new_map, new_entry); | vm_map_entry_link(new_map, new_entry); | ||||
vmspace_map_entry_forked(vm1, vm2, new_entry); | vmspace_map_entry_forked(vm1, vm2, new_entry); | ||||
vm_map_copy_entry(old_map, new_map, old_entry, | vm_map_copy_entry(old_map, new_map, old_entry, | ||||
new_entry, fork_charge); | new_entry, fork_charge); | ||||
vm_map_entry_set_vnode_text(new_entry, true); | vm_map_entry_set_vnode_text(new_entry, true); | ||||
break; | break; | ||||
case VM_INHERIT_ZERO: | case VM_INHERIT_ZERO: | ||||
/* | /* | ||||
* Create a new anonymous mapping entry modelled from | * Create a new anonymous mapping entry modelled from | ||||
* the old one. | * the old one. | ||||
*/ | */ | ||||
new_entry = vm_map_entry_create(new_map); | new_entry = vm_map_entry_create(new_map); | ||||
memset(new_entry, 0, sizeof(*new_entry)); | memset(new_entry, 0, sizeof(*new_entry)); | ||||
new_entry->start = old_entry->start; | new_entry->start = old_entry->start; | ||||
new_entry->end = old_entry->end; | new_entry->end = old_entry->end; | ||||
new_entry->eflags = old_entry->eflags & | new_entry->eflags = old_entry->eflags & | ||||
~(MAP_ENTRY_USER_WIRED | MAP_ENTRY_IN_TRANSITION | | ~(MAP_ENTRY_USER_WIRED | MAP_ENTRY_IN_TRANSITION | | ||||
MAP_ENTRY_VN_WRITECNT | MAP_ENTRY_VN_EXEC); | MAP_ENTRY_WRITECNT | MAP_ENTRY_VN_EXEC); | ||||
new_entry->protection = old_entry->protection; | new_entry->protection = old_entry->protection; | ||||
new_entry->max_protection = old_entry->max_protection; | new_entry->max_protection = old_entry->max_protection; | ||||
new_entry->inheritance = VM_INHERIT_ZERO; | new_entry->inheritance = VM_INHERIT_ZERO; | ||||
vm_map_entry_link(new_map, new_entry); | vm_map_entry_link(new_map, new_entry); | ||||
vmspace_map_entry_forked(vm1, vm2, new_entry); | vmspace_map_entry_forked(vm1, vm2, new_entry); | ||||
new_entry->cred = curthread->td_ucred; | new_entry->cred = curthread->td_ucred; | ||||
▲ Show 20 Lines • Show All 865 Lines • Show Last 20 Lines |