* This should only be used by lockless functions for releasing transient * incorrect acquires. The page may have been freed after we acquired a * busy lock. In this case busy_lock == VPB_FREED and we have nothing * further to do. */
| 1738 | * further to do. |
| 1739 | */ |
| 1740 | static void |
| 1741 | vm_page_busy_release(vm_page_t m) |
| 1742 | { |
| 1743 | u_int x; |
| 1744 | |
| 1745 | x = vm_page_busy_fetch(m); |
| 1746 | for (;;) { |
| 1747 | if (x == VPB_FREED) |
| 1748 | break; |
| 1749 | if ((x & VPB_BIT_SHARED) != 0 && VPB_SHARERS(x) > 1) { |
| 1750 | if (atomic_fcmpset_int(&m->busy_lock, &x, |
| 1751 | x - VPB_ONE_SHARER)) |
| 1752 | break; |
| 1753 | continue; |
| 1754 | } |
| 1755 | KASSERT((x & VPB_BIT_SHARED) != 0 || |
| 1756 | (x & ~VPB_BIT_WAITERS) == VPB_CURTHREAD_EXCLUSIVE, |
| 1757 | ("vm_page_busy_release: %p xbusy not owned.", m)); |
| 1758 | if (!atomic_fcmpset_rel_int(&m->busy_lock, &x, VPB_UNBUSIED)) |
| 1759 | continue; |
| 1760 | if ((x & VPB_BIT_WAITERS) != 0) |
| 1761 | wakeup(m); |
| 1762 | break; |
| 1763 | } |
| 1764 | } |
| 1765 | |
| 1766 | /* |
| 1767 | * vm_page_find_least: |
no test coverage detected