Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_map.c
Show First 20 Lines • Show All 1,467 Lines • ▼ Show 20 Lines | charged: | ||||
if (object != NULL) { | if (object != NULL) { | ||||
/* | /* | ||||
* OBJ_ONEMAPPING must be cleared unless this mapping | * OBJ_ONEMAPPING must be cleared unless this mapping | ||||
* is trivially proven to be the only mapping for any | * is trivially proven to be the only mapping for any | ||||
* of the object's pages. (Object granularity | * of the object's pages. (Object granularity | ||||
* reference counting is insufficient to recognize | * reference counting is insufficient to recognize | ||||
* aliases with precision.) | * aliases with precision.) | ||||
*/ | */ | ||||
if ((object->flags & OBJ_ANON) != 0) { | |||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
if (object->ref_count > 1 || object->shadow_count != 0) | if (object->ref_count > 1 || object->shadow_count != 0) | ||||
kib: BTW, I do not think that we can observe ref_count == 1 and then ref_count > 1 there. | |||||
vm_object_clear_flag(object, OBJ_ONEMAPPING); | vm_object_clear_flag(object, OBJ_ONEMAPPING); | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
} | |||||
} else if ((prev_entry->eflags & ~MAP_ENTRY_USER_WIRED) == | } else if ((prev_entry->eflags & ~MAP_ENTRY_USER_WIRED) == | ||||
protoeflags && | protoeflags && | ||||
(cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP | | (cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP | | ||||
MAP_VN_EXEC)) == 0 && | MAP_VN_EXEC)) == 0 && | ||||
prev_entry->end == start && (prev_entry->cred == cred || | prev_entry->end == start && (prev_entry->cred == cred || | ||||
(prev_entry->object.vm_object != NULL && | (prev_entry->object.vm_object != NULL && | ||||
prev_entry->object.vm_object->cred == cred)) && | prev_entry->object.vm_object->cred == cred)) && | ||||
vm_object_coalesce(prev_entry->object.vm_object, | vm_object_coalesce(prev_entry->object.vm_object, | ||||
▲ Show 20 Lines • Show All 576 Lines • ▼ Show 20 Lines | |||||
vm_map_entry_back(vm_map_entry_t entry) | vm_map_entry_back(vm_map_entry_t entry) | ||||
{ | { | ||||
vm_object_t object; | vm_object_t object; | ||||
KASSERT(entry->object.vm_object == NULL, | KASSERT(entry->object.vm_object == NULL, | ||||
("map entry %p has backing object", entry)); | ("map entry %p has backing object", entry)); | ||||
KASSERT((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0, | KASSERT((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0, | ||||
("map entry %p is a submap", entry)); | ("map entry %p is a submap", entry)); | ||||
object = vm_object_allocate(OBJT_DEFAULT, | object = vm_object_allocate_anon(atop(entry->end - entry->start)); | ||||
atop(entry->end - entry->start)); | |||||
entry->object.vm_object = object; | entry->object.vm_object = object; | ||||
entry->offset = 0; | entry->offset = 0; | ||||
if (entry->cred != NULL) { | if (entry->cred != NULL) { | ||||
object->cred = entry->cred; | object->cred = entry->cred; | ||||
object->charge = entry->end - entry->start; | object->charge = entry->end - entry->start; | ||||
entry->cred = NULL; | entry->cred = NULL; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,360 Lines • ▼ Show 20 Lines | vm_map_entry_delete(vm_map_t map, vm_map_entry_t entry) | ||||
size = entry->end - entry->start; | size = entry->end - entry->start; | ||||
map->size -= size; | map->size -= size; | ||||
if (entry->cred != NULL) { | if (entry->cred != NULL) { | ||||
swap_release_by_cred(size, entry->cred); | swap_release_by_cred(size, entry->cred); | ||||
crfree(entry->cred); | crfree(entry->cred); | ||||
} | } | ||||
dougmUnsubmitted Not Done Inline ActionsNo need for goto. if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0 || object == NULL) entry->object.vm_object = NULL; else if ((object->flags & OBJ_ANON) != 0 || object == kernel_object) { dougm: No need for goto.
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0 || object == NULL)… | |||||
dougmUnsubmitted Not Done Inline ActionsYou may have failed to observe this comment. dougm: You may have failed to observe this comment. | |||||
jeffAuthorUnsubmitted Done Inline ActionsI saw thanks. I will fix these two comments and post an updated patch. jeff: I saw thanks. I will fix these two comments and post an updated patch. | |||||
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0 && | if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0 && | ||||
(object != NULL)) { | (object != NULL)) { | ||||
if ((object->flags & OBJ_ANON) == 0 && | |||||
object != kernel_object) | |||||
goto out; | |||||
KASSERT(entry->cred == NULL || object->cred == NULL || | KASSERT(entry->cred == NULL || object->cred == NULL || | ||||
(entry->eflags & MAP_ENTRY_NEEDS_COPY), | (entry->eflags & MAP_ENTRY_NEEDS_COPY), | ||||
("OVERCOMMIT vm_map_entry_delete: both cred %p", entry)); | ("OVERCOMMIT vm_map_entry_delete: both cred %p", entry)); | ||||
count = atop(size); | count = atop(size); | ||||
offidxstart = OFF_TO_IDX(entry->offset); | offidxstart = OFF_TO_IDX(entry->offset); | ||||
offidxend = offidxstart + count; | offidxend = offidxstart + count; | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
if (object->ref_count != 1 && ((object->flags & (OBJ_NOSPLIT | | if (object->ref_count != 1 && | ||||
OBJ_ONEMAPPING)) == OBJ_ONEMAPPING || | ((object->flags & OBJ_ONEMAPPING) != 0 || | ||||
object == kernel_object)) { | object == kernel_object)) { | ||||
vm_object_collapse(object); | vm_object_collapse(object); | ||||
/* | /* | ||||
* The option OBJPR_NOTMAPPED can be passed here | * The option OBJPR_NOTMAPPED can be passed here | ||||
* because vm_map_delete() already performed | * because vm_map_delete() already performed | ||||
* pmap_remove() on the only mapping to this range | * pmap_remove() on the only mapping to this range | ||||
* of pages. | * of pages. | ||||
Show All 15 Lines | if (object->ref_count != 1 && | ||||
object->cred); | object->cred); | ||||
object->charge -= ptoa(size1); | object->charge -= ptoa(size1); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
} else | } else | ||||
entry->object.vm_object = NULL; | entry->object.vm_object = NULL; | ||||
out: | |||||
if (map->system_map) | if (map->system_map) | ||||
vm_map_entry_deallocate(entry, TRUE); | vm_map_entry_deallocate(entry, TRUE); | ||||
else { | else { | ||||
entry->next = curthread->td_map_def_user; | entry->next = curthread->td_map_def_user; | ||||
curthread->td_map_def_user = entry; | curthread->td_map_def_user = entry; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | if (src_entry->wired_count == 0 || | ||||
/* | /* | ||||
* Make a copy of the object. | * Make a copy of the object. | ||||
*/ | */ | ||||
size = src_entry->end - src_entry->start; | size = src_entry->end - src_entry->start; | ||||
if ((src_object = src_entry->object.vm_object) != NULL) { | if ((src_object = src_entry->object.vm_object) != NULL) { | ||||
VM_OBJECT_WLOCK(src_object); | VM_OBJECT_WLOCK(src_object); | ||||
charged = ENTRY_CHARGED(src_entry); | charged = ENTRY_CHARGED(src_entry); | ||||
if (src_object->handle == NULL && | if (src_object->handle == NULL && | ||||
(src_object->type == OBJT_DEFAULT || | (src_object->flags & OBJ_ANON) != 0) { | ||||
src_object->type == OBJT_SWAP)) { | |||||
vm_object_collapse(src_object); | vm_object_collapse(src_object); | ||||
if ((src_object->flags & (OBJ_NOSPLIT | | if ((src_object->flags & OBJ_ONEMAPPING) != 0) { | ||||
OBJ_ONEMAPPING)) == OBJ_ONEMAPPING) { | |||||
vm_object_split(src_entry); | vm_object_split(src_entry); | ||||
src_object = | src_object = | ||||
src_entry->object.vm_object; | src_entry->object.vm_object; | ||||
} | } | ||||
} | } | ||||
vm_object_reference_locked(src_object); | vm_object_reference_locked(src_object); | ||||
vm_object_clear_flag(src_object, OBJ_ONEMAPPING); | vm_object_clear_flag(src_object, OBJ_ONEMAPPING); | ||||
if (src_entry->cred != NULL && | if (src_entry->cred != NULL && | ||||
▲ Show 20 Lines • Show All 914 Lines • ▼ Show 20 Lines | RetryLookupLocked: | ||||
/* | /* | ||||
* Create an object if necessary. | * Create an object if necessary. | ||||
*/ | */ | ||||
if (entry->object.vm_object == NULL && | if (entry->object.vm_object == NULL && | ||||
!map->system_map) { | !map->system_map) { | ||||
if (vm_map_lock_upgrade(map)) | if (vm_map_lock_upgrade(map)) | ||||
goto RetryLookup; | goto RetryLookup; | ||||
entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT, | entry->object.vm_object = vm_object_allocate_anon(atop(size)); | ||||
atop(size)); | |||||
entry->offset = 0; | entry->offset = 0; | ||||
if (entry->cred != NULL) { | if (entry->cred != NULL) { | ||||
VM_OBJECT_WLOCK(entry->object.vm_object); | VM_OBJECT_WLOCK(entry->object.vm_object); | ||||
entry->object.vm_object->cred = entry->cred; | entry->object.vm_object->cred = entry->cred; | ||||
entry->object.vm_object->charge = size; | entry->object.vm_object->charge = size; | ||||
VM_OBJECT_WUNLOCK(entry->object.vm_object); | VM_OBJECT_WUNLOCK(entry->object.vm_object); | ||||
entry->cred = NULL; | entry->cred = NULL; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 276 Lines • Show Last 20 Lines |
BTW, I do not think that we can observe ref_count == 1 and then ref_count > 1 there.