diff options
author | Mark Johnston <markj@FreeBSD.org> | 2021-11-15 16:35:44 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2021-11-15 18:01:30 +0000 |
commit | 87b646630c4892e21446cd096bea6bcaecea33ac (patch) | |
tree | 576a9259bd27b62ce891154313b7ad1205255e55 /sys/vm/vm_page.c | |
parent | b0acc3f11ba31f0aea8ca5ce2720b481dfa79d1b (diff) | |
download | src-87b646630c4892e21446cd096bea6bcaecea33ac.tar.gz src-87b646630c4892e21446cd096bea6bcaecea33ac.zip |
vm_page: Consolidate page busy sleep mechanisms
- Modify vm_page_busy_sleep() and vm_page_busy_sleep_unlocked() to take
a VM_ALLOC_* flag indicating whether to sleep on shared-busy, and fix
up callers.
- Modify vm_page_busy_sleep() to return a status indicating whether the
object lock was dropped, and fix up callers.
- Convert callers of vm_page_sleep_if_busy() to use vm_page_busy_sleep()
instead.
- Remove vm_page_sleep_if_(x)busy().
No functional change intended.
Obtained from: jeff (object_concurrency patches)
Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D32947
Diffstat (limited to 'sys/vm/vm_page.c')
-rw-r--r-- | sys/vm/vm_page.c | 97 |
1 files changed, 17 insertions, 80 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index ac710bf43d08..28eb95d9fb33 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1000,24 +1000,26 @@ vm_page_sunbusy(vm_page_t m) * vm_page_busy_sleep: * * 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 VM_ALLOC_IGN_SBUSY is specified in allocflags, the function + * will not sleep if the page is shared-busy. * - * If nonshared is true, sleep only if the page is xbusy. + * The object lock must be held on entry. * - * The object lock must be held on entry and will be released on exit. + * Returns true if it slept and dropped the object lock, or false + * if there was no sleep and the lock is still held. */ -void -vm_page_busy_sleep(vm_page_t m, const char *wmesg, bool nonshared) +bool +vm_page_busy_sleep(vm_page_t m, const char *wmesg, int allocflags) { vm_object_t obj; obj = m->object; VM_OBJECT_ASSERT_LOCKED(obj); - vm_page_lock_assert(m, MA_NOTOWNED); - if (!_vm_page_busy_sleep(obj, m, m->pindex, wmesg, - nonshared ? VM_ALLOC_SBUSY : 0 , true)) - VM_OBJECT_DROP(obj); + return (_vm_page_busy_sleep(obj, m, m->pindex, wmesg, allocflags, + true)); } /* @@ -1026,21 +1028,19 @@ vm_page_busy_sleep(vm_page_t m, const char *wmesg, bool nonshared) * Sleep if the page is busy, using the page pointer as wchan. * 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 * return if the page changes identity. */ void 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_page_lock_assert(m, MA_NOTOWNED); - _vm_page_busy_sleep(obj, m, pindex, wmesg, - nonshared ? VM_ALLOC_SBUSY : 0, false); + (void)_vm_page_busy_sleep(obj, m, pindex, wmesg, allocflags, false); } /* @@ -1050,6 +1050,8 @@ vm_page_busy_sleep_unlocked(vm_object_t obj, vm_page_t m, vm_pindex_t pindex, * lockstate against parameters. Returns true if it sleeps and * 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 * and held for any false returns. */ @@ -1396,71 +1398,6 @@ vm_page_free_invalid(vm_page_t 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 ] * * Set all bits in the page's dirty field. |