Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_pageout.c
Show First 20 Lines • Show All 1,301 Lines • ▼ Show 20 Lines | if (object->ref_count != 0) | ||||
act_delta = pmap_ts_referenced(m); | act_delta = pmap_ts_referenced(m); | ||||
else | else | ||||
act_delta = 0; | act_delta = 0; | ||||
if ((m->a.flags & PGA_REFERENCED) != 0) { | if ((m->a.flags & PGA_REFERENCED) != 0) { | ||||
vm_page_aflag_clear(m, PGA_REFERENCED); | vm_page_aflag_clear(m, PGA_REFERENCED); | ||||
act_delta++; | act_delta++; | ||||
} | } | ||||
/* Deferred free of swap space. */ | |||||
if ((m->a.flags & PGA_SWAP_FREE) != 0 && | |||||
VM_OBJECT_TRYWLOCK(object)) { | |||||
if (m->object == object) | |||||
kib: Don't we need to recheck PGA_UNSWAPPED after locking the object ? It might be coincidental… | |||||
Not Done Inline ActionsI think you are right. There is also no guarantee that the object pointer is not stale, so that must be rechecked as well. markj: I think you are right. There is also no guarantee that the object pointer is not stale, so that… | |||||
Done Inline ActionsI see I will fix this. Incidentally with recent changes it would be rendered harmless. We would see that object is not locked and just make sure the bits were right. jeff: I see I will fix this. Incidentally with recent changes it would be rendered harmless. We… | |||||
vm_pager_page_unswapped(m); | |||||
VM_OBJECT_WUNLOCK(object); | |||||
} | |||||
/* | /* | ||||
* Advance or decay the act_count based on recent usage. | * Advance or decay the act_count based on recent usage. | ||||
*/ | */ | ||||
if (act_delta != 0) { | if (act_delta != 0) { | ||||
m->a.act_count += ACT_ADVANCE + act_delta; | m->a.act_count += ACT_ADVANCE + act_delta; | ||||
if (m->a.act_count > ACT_MAX) | if (m->a.act_count > ACT_MAX) | ||||
m->a.act_count = ACT_MAX; | m->a.act_count = ACT_MAX; | ||||
} else | } else | ||||
▲ Show 20 Lines • Show All 218 Lines • ▼ Show 20 Lines | if (vm_page_tryxbusy(m) == 0) { | ||||
* are being paged out and will leave the | * are being paged out and will leave the | ||||
* queue shortly after the scan finishes. So, | * queue shortly after the scan finishes. So, | ||||
* they ought to be discounted from the | * they ought to be discounted from the | ||||
* inactive count. | * inactive count. | ||||
*/ | */ | ||||
addl_page_shortage++; | addl_page_shortage++; | ||||
goto reinsert; | goto reinsert; | ||||
} | } | ||||
/* Deferred free of swap space. */ | |||||
if ((m->a.flags & PGA_SWAP_FREE) != 0) | |||||
vm_pager_page_unswapped(m); | |||||
/* | /* | ||||
* Re-check for wirings now that we hold the object lock and | * Re-check for wirings now that we hold the object lock and | ||||
Not Done Inline ActionsDon't we need to do this while laundering as well? Suppose a page in the laundry queue is dirty and has UNSWAPPED set. We may page out its contents and mark it clean, but I don't see how PGA_UNSWAPPED gets cleared at that point. markj: Don't we need to do this while laundering as well? Suppose a page in the laundry queue is dirty… | |||||
* have verified that the page is unbusied. If the page is | * have verified that the page is unbusied. If the page is | ||||
* mapped, it may still be wired by pmap lookups. The call to | * mapped, it may still be wired by pmap lookups. The call to | ||||
* vm_page_try_remove_all() below atomically checks for such | * vm_page_try_remove_all() below atomically checks for such | ||||
* wirings and removes mappings. If the page is unmapped, the | * wirings and removes mappings. If the page is unmapped, the | ||||
* wire count is guaranteed not to increase. | * wire count is guaranteed not to increase. | ||||
*/ | */ | ||||
if (__predict_false(vm_page_wired(m))) { | if (__predict_false(vm_page_wired(m))) { | ||||
vm_page_xunbusy(m); | vm_page_xunbusy(m); | ||||
▲ Show 20 Lines • Show All 710 Lines • Show Last 20 Lines |
Don't we need to recheck PGA_UNSWAPPED after locking the object ? It might be coincidental, but clearing happens only under the object lock, and this prevents unlikely race.