Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
Show First 20 Lines • Show All 994 Lines • ▼ Show 20 Lines | for (;;) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* vm_page_busy_sleep: | * vm_page_busy_sleep: | ||||
* | * | ||||
* Sleep if the page is busy, using the page pointer as wchan. | * Sleep if the page is busy, using the page pointer as wchan. | ||||
* This is used to implement the hard-path of busying mechanism. | * This is used to implement the hard-path of the busying mechanism. | ||||
* | * | ||||
* If nonshared is true, sleep only if the page is xbusy. | * If VM_ALLOC_IGN_SBUSY is specified in allocflags, the function | ||||
* will not sleep if the page is shared-busy. | |||||
* | * | ||||
* The object lock must be held on entry and will be released on exit. | * The object lock must be held on entry. | ||||
* | |||||
* Returns true if it slept and dropped the object lock, or false | |||||
* if there was no sleep and the lock is still held. | |||||
*/ | */ | ||||
void | bool | ||||
vm_page_busy_sleep(vm_page_t m, const char *wmesg, bool nonshared) | vm_page_busy_sleep(vm_page_t m, const char *wmesg, int allocflags) | ||||
{ | { | ||||
vm_object_t obj; | vm_object_t obj; | ||||
obj = m->object; | obj = m->object; | ||||
VM_OBJECT_ASSERT_LOCKED(obj); | VM_OBJECT_ASSERT_LOCKED(obj); | ||||
vm_page_lock_assert(m, MA_NOTOWNED); | |||||
if (!_vm_page_busy_sleep(obj, m, m->pindex, wmesg, | return (_vm_page_busy_sleep(obj, m, m->pindex, wmesg, allocflags, | ||||
nonshared ? VM_ALLOC_SBUSY : 0 , true)) | true)); | ||||
VM_OBJECT_DROP(obj); | |||||
} | } | ||||
/* | /* | ||||
* vm_page_busy_sleep_unlocked: | * vm_page_busy_sleep_unlocked: | ||||
* | * | ||||
* Sleep if the page is busy, using the page pointer as wchan. | * Sleep if the page is busy, using the page pointer as wchan. | ||||
* This is used to implement the hard-path of busying mechanism. | * This is used to implement the hard-path of busying mechanism. | ||||
* | * | ||||
* If nonshared is true, sleep only if the page is xbusy. | * If VM_ALLOC_IGN_SBUSY is specified in allocflags, the function | ||||
* will not sleep if the page is shared-busy. | |||||
* | * | ||||
* The object lock must not be held on entry. The operation will | * The object lock must not be held on entry. The operation will | ||||
* return if the page changes identity. | * return if the page changes identity. | ||||
*/ | */ | ||||
void | void | ||||
vm_page_busy_sleep_unlocked(vm_object_t obj, vm_page_t m, vm_pindex_t pindex, | vm_page_busy_sleep_unlocked(vm_object_t obj, vm_page_t m, vm_pindex_t pindex, | ||||
const char *wmesg, bool nonshared) | const char *wmesg, int allocflags) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_UNLOCKED(obj); | VM_OBJECT_ASSERT_UNLOCKED(obj); | ||||
vm_page_lock_assert(m, MA_NOTOWNED); | |||||
_vm_page_busy_sleep(obj, m, pindex, wmesg, | (void)_vm_page_busy_sleep(obj, m, pindex, wmesg, allocflags, false); | ||||
nonshared ? VM_ALLOC_SBUSY : 0, false); | |||||
} | } | ||||
/* | /* | ||||
* _vm_page_busy_sleep: | * _vm_page_busy_sleep: | ||||
* | * | ||||
* Internal busy sleep function. Verifies the page identity and | * Internal busy sleep function. Verifies the page identity and | ||||
* lockstate against parameters. Returns true if it sleeps and | * lockstate against parameters. Returns true if it sleeps and | ||||
* false otherwise. | * false otherwise. | ||||
* | * | ||||
* allocflags uses VM_ALLOC_* flags to specify the lock required. | |||||
* | |||||
* If locked is true the lock will be dropped for any true returns | * If locked is true the lock will be dropped for any true returns | ||||
* and held for any false returns. | * and held for any false returns. | ||||
*/ | */ | ||||
static bool | static bool | ||||
_vm_page_busy_sleep(vm_object_t obj, vm_page_t m, vm_pindex_t pindex, | _vm_page_busy_sleep(vm_object_t obj, vm_page_t m, vm_pindex_t pindex, | ||||
const char *wmesg, int allocflags, bool locked) | const char *wmesg, int allocflags, bool locked) | ||||
{ | { | ||||
bool xsleep; | bool xsleep; | ||||
▲ Show 20 Lines • Show All 327 Lines • ▼ Show 20 Lines | vm_page_free_invalid(vm_page_t m) | ||||
* If someone has wired this page while the object lock | * If someone has wired this page while the object lock | ||||
* was not held, then the thread that unwires is responsible | * was not held, then the thread that unwires is responsible | ||||
* for freeing the page. Otherwise just free the page now. | * for freeing the page. Otherwise just free the page now. | ||||
* The wire count of this unmapped page cannot change while | * The wire count of this unmapped page cannot change while | ||||
* we have the page xbusy and the page's object wlocked. | * we have the page xbusy and the page's object wlocked. | ||||
*/ | */ | ||||
if (vm_page_remove(m)) | if (vm_page_remove(m)) | ||||
vm_page_free(m); | vm_page_free(m); | ||||
} | |||||
/* | |||||
* vm_page_sleep_if_busy: | |||||
* | |||||
* Sleep and release the object lock if the page is busied. | |||||
* Returns TRUE if the thread slept. | |||||
* | |||||
* The given page must be unlocked and object containing it must | |||||
* be locked. | |||||
*/ | |||||
int | |||||
vm_page_sleep_if_busy(vm_page_t m, const char *wmesg) | |||||
{ | |||||
vm_object_t obj; | |||||
vm_page_lock_assert(m, MA_NOTOWNED); | |||||
VM_OBJECT_ASSERT_WLOCKED(m->object); | |||||
/* | |||||
* The page-specific object must be cached because page | |||||
* identity can change during the sleep, causing the | |||||
* re-lock of a different object. | |||||
* It is assumed that a reference to the object is already | |||||
* held by the callers. | |||||
*/ | |||||
obj = m->object; | |||||
if (_vm_page_busy_sleep(obj, m, m->pindex, wmesg, 0, true)) { | |||||
VM_OBJECT_WLOCK(obj); | |||||
return (TRUE); | |||||
} | |||||
return (FALSE); | |||||
} | |||||
/* | |||||
* vm_page_sleep_if_xbusy: | |||||
* | |||||
* Sleep and release the object lock if the page is xbusied. | |||||
* Returns TRUE if the thread slept. | |||||
* | |||||
* The given page must be unlocked and object containing it must | |||||
* be locked. | |||||
*/ | |||||
int | |||||
vm_page_sleep_if_xbusy(vm_page_t m, const char *wmesg) | |||||
{ | |||||
vm_object_t obj; | |||||
vm_page_lock_assert(m, MA_NOTOWNED); | |||||
VM_OBJECT_ASSERT_WLOCKED(m->object); | |||||
/* | |||||
* The page-specific object must be cached because page | |||||
* identity can change during the sleep, causing the | |||||
* re-lock of a different object. | |||||
* It is assumed that a reference to the object is already | |||||
* held by the callers. | |||||
*/ | |||||
obj = m->object; | |||||
if (_vm_page_busy_sleep(obj, m, m->pindex, wmesg, VM_ALLOC_SBUSY, | |||||
true)) { | |||||
VM_OBJECT_WLOCK(obj); | |||||
return (TRUE); | |||||
} | |||||
return (FALSE); | |||||
} | } | ||||
/* | /* | ||||
* vm_page_dirty_KBI: [ internal use only ] | * vm_page_dirty_KBI: [ internal use only ] | ||||
* | * | ||||
* Set all bits in the page's dirty field. | * Set all bits in the page's dirty field. | ||||
* | * | ||||
* The object containing the specified page must be locked if the | * The object containing the specified page must be locked if the | ||||
▲ Show 20 Lines • Show All 4,203 Lines • Show Last 20 Lines |