Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
Show First 20 Lines • Show All 1,477 Lines • ▼ Show 20 Lines | vm_page_insert_after(vm_page_t m, vm_object_t object, vm_pindex_t pindex, | ||||
*/ | */ | ||||
if (vm_radix_insert(&object->rtree, m)) { | if (vm_radix_insert(&object->rtree, m)) { | ||||
m->object = NULL; | m->object = NULL; | ||||
m->pindex = 0; | m->pindex = 0; | ||||
m->ref_count &= ~VPRC_OBJREF; | m->ref_count &= ~VPRC_OBJREF; | ||||
return (1); | return (1); | ||||
} | } | ||||
vm_page_insert_radixdone(m, object, mpred); | vm_page_insert_radixdone(m, object, mpred); | ||||
vm_pager_page_inserted(object, m); | |||||
markj: We should call this pager op in vm_page_rename() as well. | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* vm_page_insert_radixdone: | * vm_page_insert_radixdone: | ||||
* | * | ||||
* Complete page "m" insertion into the specified object after the | * Complete page "m" insertion into the specified object after the | ||||
* radix trie hooking. | * radix trie hooking. | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | vm_page_object_remove(vm_page_t m) | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | VM_OBJECT_ASSERT_WLOCKED(object); | ||||
KASSERT((m->ref_count & VPRC_OBJREF) != 0, | KASSERT((m->ref_count & VPRC_OBJREF) != 0, | ||||
("page %p is missing its object ref", m)); | ("page %p is missing its object ref", m)); | ||||
/* Deferred free of swap space. */ | /* Deferred free of swap space. */ | ||||
if ((m->a.flags & PGA_SWAP_FREE) != 0) | if ((m->a.flags & PGA_SWAP_FREE) != 0) | ||||
vm_pager_page_unswapped(m); | vm_pager_page_unswapped(m); | ||||
vm_pager_page_removed(object, m); | |||||
m->object = NULL; | m->object = NULL; | ||||
mrem = vm_radix_remove(&object->rtree, m->pindex); | mrem = vm_radix_remove(&object->rtree, m->pindex); | ||||
KASSERT(mrem == m, ("removed page %p, expected page %p", mrem, m)); | KASSERT(mrem == m, ("removed page %p, expected page %p", mrem, m)); | ||||
/* | /* | ||||
* Now remove from the object's list of backed pages. | * Now remove from the object's list of backed pages. | ||||
*/ | */ | ||||
TAILQ_REMOVE(&object->memq, m, listq); | TAILQ_REMOVE(&object->memq, m, listq); | ||||
▲ Show 20 Lines • Show All 306 Lines • ▼ Show 20 Lines | vm_page_rename(vm_page_t m, vm_object_t new_object, vm_pindex_t new_pindex) | ||||
vm_page_object_remove(m); | vm_page_object_remove(m); | ||||
/* Return back to the new pindex to complete vm_page_insert(). */ | /* Return back to the new pindex to complete vm_page_insert(). */ | ||||
m->pindex = new_pindex; | m->pindex = new_pindex; | ||||
m->object = new_object; | m->object = new_object; | ||||
vm_page_insert_radixdone(m, new_object, mpred); | vm_page_insert_radixdone(m, new_object, mpred); | ||||
vm_page_dirty(m); | vm_page_dirty(m); | ||||
vm_pager_page_inserted(new_object, m); | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* vm_page_alloc: | * vm_page_alloc: | ||||
* | * | ||||
* Allocate and return a page that is associated with the specified | * Allocate and return a page that is associated with the specified | ||||
* object and offset pair. By default, this page is exclusive busied. | * object and offset pair. By default, this page is exclusive busied. | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | KASSERT(((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) != | ||||
("invalid request %#x", req)); | ("invalid request %#x", req)); | ||||
KASSERT(mpred == NULL || mpred->pindex < pindex, | KASSERT(mpred == NULL || mpred->pindex < pindex, | ||||
("mpred %p doesn't precede pindex 0x%jx", mpred, | ("mpred %p doesn't precede pindex 0x%jx", mpred, | ||||
(uintmax_t)pindex)); | (uintmax_t)pindex)); | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | VM_OBJECT_ASSERT_WLOCKED(object); | ||||
flags = 0; | flags = 0; | ||||
m = NULL; | m = NULL; | ||||
if (!vm_pager_can_alloc_page(object, pindex)) | |||||
return (NULL); | |||||
again: | again: | ||||
#if VM_NRESERVLEVEL > 0 | #if VM_NRESERVLEVEL > 0 | ||||
/* | /* | ||||
* Can we allocate the page from a reservation? | * Can we allocate the page from a reservation? | ||||
*/ | */ | ||||
if (vm_object_reserv(object) && | if (vm_object_reserv(object) && | ||||
(m = vm_reserv_alloc_page(object, pindex, domain, req, mpred)) != | (m = vm_reserv_alloc_page(object, pindex, domain, req, mpred)) != | ||||
NULL) { | NULL) { | ||||
▲ Show 20 Lines • Show All 2,655 Lines • ▼ Show 20 Lines | if ((allocflags & VM_ALLOC_NOCREAT) != 0) { | ||||
vm_page_busy_release(m); | vm_page_busy_release(m); | ||||
*mp = NULL; | *mp = NULL; | ||||
return (VM_PAGER_FAIL); | return (VM_PAGER_FAIL); | ||||
} | } | ||||
} else if ((allocflags & VM_ALLOC_NOCREAT) != 0) { | } else if ((allocflags & VM_ALLOC_NOCREAT) != 0) { | ||||
*mp = NULL; | *mp = NULL; | ||||
return (VM_PAGER_FAIL); | return (VM_PAGER_FAIL); | ||||
} else if ((m = vm_page_alloc(object, pindex, pflags)) == NULL) { | } else if ((m = vm_page_alloc(object, pindex, pflags)) == NULL) { | ||||
if (!vm_pager_can_alloc_page(object, pindex)) | |||||
return (VM_PAGER_AGAIN); | |||||
goto retrylookup; | goto retrylookup; | ||||
} | } | ||||
vm_page_assert_xbusied(m); | vm_page_assert_xbusied(m); | ||||
if (vm_pager_has_page(object, pindex, NULL, &after)) { | if (vm_pager_has_page(object, pindex, NULL, &after)) { | ||||
after = MIN(after, VM_INITIAL_PAGEIN); | after = MIN(after, VM_INITIAL_PAGEIN); | ||||
after = MIN(after, allocflags >> VM_ALLOC_COUNT_SHIFT); | after = MIN(after, allocflags >> VM_ALLOC_COUNT_SHIFT); | ||||
after = MAX(after, 1); | after = MAX(after, 1); | ||||
▲ Show 20 Lines • Show All 897 Lines • Show Last 20 Lines |
We should call this pager op in vm_page_rename() as well.