Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
| Show First 20 Lines • Show All 4,269 Lines • ▼ Show 20 Lines | vm_page_unwire_managed(vm_page_t m, uint8_t nqueue, bool noreuse) | ||||
| /* | /* | ||||
| * Update LRU state before releasing the wiring reference. | * Update LRU state before releasing the wiring reference. | ||||
| * Use a release store when updating the reference count to | * Use a release store when updating the reference count to | ||||
| * synchronize with vm_page_free_prep(). | * synchronize with vm_page_free_prep(). | ||||
| */ | */ | ||||
| old = atomic_load_int(&m->ref_count); | old = atomic_load_int(&m->ref_count); | ||||
| do { | do { | ||||
| u_int count; | |||||
| KASSERT(VPRC_WIRE_COUNT(old) > 0, | KASSERT(VPRC_WIRE_COUNT(old) > 0, | ||||
| ("vm_page_unwire: wire count underflow for page %p", m)); | ("vm_page_unwire: wire count underflow for page %p", m)); | ||||
| if (old > VPRC_OBJREF + 1) { | count = old & ~VPRC_BLOCKED; | ||||
| if (count > VPRC_OBJREF + 1) { | |||||
| /* | /* | ||||
| * The page has at least one other wiring reference. An | * The page has at least one other wiring reference. An | ||||
| * earlier iteration of this loop may have called | * earlier iteration of this loop may have called | ||||
| * vm_page_release_toq() and cleared PGA_DEQUEUE, so | * vm_page_release_toq() and cleared PGA_DEQUEUE, so | ||||
| * re-set it if necessary. | * re-set it if necessary. | ||||
| */ | */ | ||||
| if ((vm_page_astate_load(m).flags & PGA_DEQUEUE) == 0) | if ((vm_page_astate_load(m).flags & PGA_DEQUEUE) == 0) | ||||
| vm_page_aflag_set(m, PGA_DEQUEUE); | vm_page_aflag_set(m, PGA_DEQUEUE); | ||||
| } else if (old == VPRC_OBJREF + 1) { | } else if (count == VPRC_OBJREF + 1) { | ||||
| /* | /* | ||||
| * This is the last wiring. Clear PGA_DEQUEUE and | * This is the last wiring. Clear PGA_DEQUEUE and | ||||
| * update the page's queue state to reflect the | * update the page's queue state to reflect the | ||||
| * reference. If the page does not belong to an object | * reference. If the page does not belong to an object | ||||
| * (i.e., the VPRC_OBJREF bit is clear), we only need to | * (i.e., the VPRC_OBJREF bit is clear), we only need to | ||||
| * clear leftover queue state. | * clear leftover queue state. | ||||
| */ | */ | ||||
| vm_page_release_toq(m, nqueue, noreuse); | vm_page_release_toq(m, nqueue, noreuse); | ||||
| } else if (old == 1) { | } else if (count == 1) { | ||||
| vm_page_aflag_clear(m, PGA_DEQUEUE); | vm_page_aflag_clear(m, PGA_DEQUEUE); | ||||
| } | } | ||||
| } while (!atomic_fcmpset_rel_int(&m->ref_count, &old, old - 1)); | } while (!atomic_fcmpset_rel_int(&m->ref_count, &old, old - 1)); | ||||
| if (VPRC_WIRE_COUNT(old) == 1) { | if (VPRC_WIRE_COUNT(old) == 1) { | ||||
| vm_wire_sub(1); | vm_wire_sub(1); | ||||
| if (old == 1) | if (old == 1) | ||||
| vm_page_free(m); | vm_page_free(m); | ||||
| ▲ Show 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | vm_page_try_blocked_op(vm_page_t m, void (*op)(vm_page_t)) | ||||
| KASSERT(vm_page_busied(m), | KASSERT(vm_page_busied(m), | ||||
| ("vm_page_try_blocked_op: page %p is not busy", m)); | ("vm_page_try_blocked_op: page %p is not busy", m)); | ||||
| VM_OBJECT_ASSERT_LOCKED(m->object); | VM_OBJECT_ASSERT_LOCKED(m->object); | ||||
| old = atomic_load_int(&m->ref_count); | old = atomic_load_int(&m->ref_count); | ||||
| do { | do { | ||||
| KASSERT(old != 0, | KASSERT(old != 0, | ||||
| ("vm_page_try_blocked_op: page %p has no references", m)); | ("vm_page_try_blocked_op: page %p has no references", m)); | ||||
| KASSERT((old & VPRC_BLOCKED) == 0, | |||||
| ("vm_page_try_blocked_op: page %p blocks wirings", m)); | |||||
| if (VPRC_WIRE_COUNT(old) != 0) | if (VPRC_WIRE_COUNT(old) != 0) | ||||
| return (false); | return (false); | ||||
| } while (!atomic_fcmpset_int(&m->ref_count, &old, old | VPRC_BLOCKED)); | } while (!atomic_fcmpset_int(&m->ref_count, &old, old | VPRC_BLOCKED)); | ||||
| (op)(m); | (op)(m); | ||||
| /* | /* | ||||
| * If the object is read-locked, new wirings may be created via an | * If the object is read-locked, new wirings may be created via an | ||||
| ▲ Show 20 Lines • Show All 1,269 Lines • Show Last 20 Lines | |||||