aboutsummaryrefslogtreecommitdiff
path: root/sys/vm/vm_page.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-11-15 16:35:44 +0000
committerMark Johnston <markj@FreeBSD.org>2021-11-15 18:01:30 +0000
commit87b646630c4892e21446cd096bea6bcaecea33ac (patch)
tree576a9259bd27b62ce891154313b7ad1205255e55 /sys/vm/vm_page.c
parentb0acc3f11ba31f0aea8ca5ce2720b481dfa79d1b (diff)
downloadsrc-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.c97
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.