Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_object.c
Show First 20 Lines • Show All 1,416 Lines • ▼ Show 20 Lines | if (vm_page_rename(m, new_object, idx)) { | ||||
vm_page_xunbusy(m); | vm_page_xunbusy(m); | ||||
VM_OBJECT_WUNLOCK(new_object); | VM_OBJECT_WUNLOCK(new_object); | ||||
VM_OBJECT_WUNLOCK(orig_object); | VM_OBJECT_WUNLOCK(orig_object); | ||||
vm_radix_wait(); | vm_radix_wait(); | ||||
VM_OBJECT_WLOCK(orig_object); | VM_OBJECT_WLOCK(orig_object); | ||||
VM_OBJECT_WLOCK(new_object); | VM_OBJECT_WLOCK(new_object); | ||||
goto retry; | goto retry; | ||||
} | } | ||||
/* Rename released the xbusy lock. */ | |||||
#if VM_NRESERVLEVEL > 0 | #if VM_NRESERVLEVEL > 0 | ||||
/* | /* | ||||
* If some of the reservation's allocated pages remain with | * If some of the reservation's allocated pages remain with | ||||
* the original object, then transferring the reservation to | * the original object, then transferring the reservation to | ||||
* the new object is neither particularly beneficial nor | * the new object is neither particularly beneficial nor | ||||
* particularly harmful as compared to leaving the reservation | * particularly harmful as compared to leaving the reservation | ||||
* with the original object. If, however, all of the | * with the original object. If, however, all of the | ||||
* reservation's allocated pages are transferred to the new | * reservation's allocated pages are transferred to the new | ||||
* object, then transferring the reservation is typically | * object, then transferring the reservation is typically | ||||
* beneficial. Determining which of these two cases applies | * beneficial. Determining which of these two cases applies | ||||
* would be more costly than unconditionally renaming the | * would be more costly than unconditionally renaming the | ||||
* reservation. | * reservation. | ||||
*/ | */ | ||||
vm_reserv_rename(m, new_object, orig_object, offidxstart); | vm_reserv_rename(m, new_object, orig_object, offidxstart); | ||||
#endif | #endif | ||||
if (orig_object->type == OBJT_SWAP) | if (orig_object->type != OBJT_SWAP) | ||||
vm_page_xbusy(m); | vm_page_xunbusy(m); | ||||
} | } | ||||
if (orig_object->type == OBJT_SWAP) { | if (orig_object->type == OBJT_SWAP) { | ||||
/* | /* | ||||
* swap_pager_copy() can sleep, in which case the orig_object's | * swap_pager_copy() can sleep, in which case the orig_object's | ||||
* and new_object's locks are released and reacquired. | * and new_object's locks are released and reacquired. | ||||
*/ | */ | ||||
swap_pager_copy(orig_object, new_object, offidxstart, 0); | swap_pager_copy(orig_object, new_object, offidxstart, 0); | ||||
TAILQ_FOREACH(m, &new_object->memq, listq) | TAILQ_FOREACH(m, &new_object->memq, listq) | ||||
▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | if (p->pindex < backing_offset_index || | ||||
* Page is out of the parent object's range, we can | * Page is out of the parent object's range, we can | ||||
* simply destroy it. | * simply destroy it. | ||||
*/ | */ | ||||
vm_page_lock(p); | vm_page_lock(p); | ||||
KASSERT(!pmap_page_is_mapped(p), | KASSERT(!pmap_page_is_mapped(p), | ||||
("freeing mapped page %p", p)); | ("freeing mapped page %p", p)); | ||||
if (vm_page_remove(p)) | if (vm_page_remove(p)) | ||||
vm_page_free(p); | vm_page_free(p); | ||||
else | |||||
vm_page_xunbusy(p); | |||||
vm_page_unlock(p); | vm_page_unlock(p); | ||||
continue; | continue; | ||||
} | } | ||||
pp = vm_page_lookup(object, new_pindex); | pp = vm_page_lookup(object, new_pindex); | ||||
if (pp != NULL && vm_page_tryxbusy(pp) == 0) { | if (pp != NULL && vm_page_tryxbusy(pp) == 0) { | ||||
vm_page_xunbusy(p); | vm_page_xunbusy(p); | ||||
/* | /* | ||||
Show All 27 Lines | if (pp != NULL || vm_pager_has_page(object, new_pindex, NULL, | ||||
if (backing_object->type == OBJT_SWAP) | if (backing_object->type == OBJT_SWAP) | ||||
swap_pager_freespace(backing_object, p->pindex, | swap_pager_freespace(backing_object, p->pindex, | ||||
1); | 1); | ||||
vm_page_lock(p); | vm_page_lock(p); | ||||
KASSERT(!pmap_page_is_mapped(p), | KASSERT(!pmap_page_is_mapped(p), | ||||
("freeing mapped page %p", p)); | ("freeing mapped page %p", p)); | ||||
if (vm_page_remove(p)) | if (vm_page_remove(p)) | ||||
vm_page_free(p); | vm_page_free(p); | ||||
else | |||||
vm_page_xunbusy(p); | |||||
vm_page_unlock(p); | vm_page_unlock(p); | ||||
if (pp != NULL) | if (pp != NULL) | ||||
vm_page_xunbusy(pp); | vm_page_xunbusy(pp); | ||||
continue; | continue; | ||||
} | } | ||||
/* | /* | ||||
* Page does not exist in parent, rename the page from the | * Page does not exist in parent, rename the page from the | ||||
* backing object to the main object. | * backing object to the main object. | ||||
* | * | ||||
* If the page was mapped to a process, it can remain mapped | * If the page was mapped to a process, it can remain mapped | ||||
* through the rename. vm_page_rename() will dirty the page. | * through the rename. vm_page_rename() will dirty the page. | ||||
*/ | */ | ||||
if (vm_page_rename(p, object, new_pindex)) { | if (vm_page_rename(p, object, new_pindex)) { | ||||
vm_page_xunbusy(p); | vm_page_xunbusy(p); | ||||
if (pp != NULL) | if (pp != NULL) | ||||
vm_page_xunbusy(pp); | vm_page_xunbusy(pp); | ||||
next = vm_object_collapse_scan_wait(object, NULL, next, | next = vm_object_collapse_scan_wait(object, NULL, next, | ||||
op); | op); | ||||
continue; | continue; | ||||
} | } | ||||
/* Rename released the xbusy lock. */ | |||||
/* Use the old pindex to free the right page. */ | /* Use the old pindex to free the right page. */ | ||||
if (backing_object->type == OBJT_SWAP) | if (backing_object->type == OBJT_SWAP) | ||||
swap_pager_freespace(backing_object, | swap_pager_freespace(backing_object, | ||||
new_pindex + backing_offset_index, 1); | new_pindex + backing_offset_index, 1); | ||||
#if VM_NRESERVLEVEL > 0 | #if VM_NRESERVLEVEL > 0 | ||||
/* | /* | ||||
* Rename the reservation. | * Rename the reservation. | ||||
*/ | */ | ||||
vm_reserv_rename(p, object, backing_object, | vm_reserv_rename(p, object, backing_object, | ||||
backing_offset_index); | backing_offset_index); | ||||
#endif | #endif | ||||
vm_page_xunbusy(p); | |||||
} | } | ||||
return (true); | return (true); | ||||
} | } | ||||
/* | /* | ||||
* this version of collapse allows the operation to occur earlier and | * this version of collapse allows the operation to occur earlier and | ||||
* when paging_in_progress is true for an object... This is not a complete | * when paging_in_progress is true for an object... This is not a complete | ||||
▲ Show 20 Lines • Show All 1,005 Lines • Show Last 20 Lines |