diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2016-06-23 08:28:13 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2016-06-23 08:28:13 +0000 |
commit | 35e8002c58e8930086a98aebb48d071a484c9dc9 (patch) | |
tree | 8d76ccde67aa54eb33b14d358e79494f64529a82 | |
parent | 505cd5d13b48ec3b068d70411da1c472af9f7e41 (diff) |
Notes
-rw-r--r-- | sys/vm/vm_page.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 5fa1f80671cd..2c89cd949c5b 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -760,17 +760,36 @@ vm_page_trysbusy(vm_page_t m) } static void +vm_page_xunbusy_locked(vm_page_t m) +{ + + vm_page_assert_xbusied(m); + vm_page_assert_locked(m); + + atomic_store_rel_int(&m->busy_lock, VPB_UNBUSIED); + /* There is a waiter, do wakeup() instead of vm_page_flash(). */ + wakeup(m); +} + +static void vm_page_xunbusy_maybelocked(vm_page_t m) { bool lockacq; vm_page_assert_xbusied(m); + /* + * Fast path for unbusy. If it succeeds, we know that there + * are no waiters, so we do not need a wakeup. + */ + if (atomic_cmpset_rel_int(&m->busy_lock, VPB_SINGLE_EXCLUSIVER, + VPB_UNBUSIED)) + return; + lockacq = !mtx_owned(vm_page_lockptr(m)); if (lockacq) vm_page_lock(m); - vm_page_flash(m); - atomic_store_rel_int(&m->busy_lock, VPB_UNBUSIED); + vm_page_xunbusy_locked(m); if (lockacq) vm_page_unlock(m); } @@ -788,8 +807,7 @@ vm_page_xunbusy_hard(vm_page_t m) vm_page_assert_xbusied(m); vm_page_lock(m); - atomic_store_rel_int(&m->busy_lock, VPB_UNBUSIED); - wakeup(m); + vm_page_xunbusy_locked(m); vm_page_unlock(m); } |