Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_pageout.c
Show First 20 Lines • Show All 1,275 Lines • ▼ Show 20 Lines | while ((m = vm_pageout_next(&ss, false)) != NULL) { | ||||
* because the page is not mapped. | * because the page is not mapped. | ||||
* 2) The count was transitioning to one, but we saw zero. | * 2) The count was transitioning to one, but we saw zero. | ||||
* This race delays the detection of a new reference. At | * This race delays the detection of a new reference. At | ||||
* worst, we will deactivate and reactivate the page. | * worst, we will deactivate and reactivate the page. | ||||
*/ | */ | ||||
refs = object->ref_count != 0 ? pmap_ts_referenced(m) : 0; | refs = object->ref_count != 0 ? pmap_ts_referenced(m) : 0; | ||||
old = vm_page_astate_load(m); | old = vm_page_astate_load(m); | ||||
ps_delta = 0; | |||||
do { | do { | ||||
/* | /* | ||||
* Check to see if the page has been removed from the | * Check to see if the page has been removed from the | ||||
* queue since the first such check. Leave it alone if | * queue since the first such check. Leave it alone if | ||||
* so, discarding any references collected by | * so, discarding any references collected by | ||||
* pmap_ts_referenced(). | * pmap_ts_referenced(). | ||||
*/ | */ | ||||
if (__predict_false(_vm_page_queue(old) == PQ_NONE)) | if (__predict_false(_vm_page_queue(old) == PQ_NONE)) | ||||
break; | break; | ||||
markj: I guess this is the only case where we can end up with a bogus ps_delta. It should be quite… | |||||
vangyzenAuthorUnsubmitted Done Inline ActionsIndeed. Thank you. vangyzen: Indeed. Thank you. | |||||
/* | /* | ||||
* Advance or decay the act_count based on recent usage. | * Advance or decay the act_count based on recent usage. | ||||
*/ | */ | ||||
new = old; | new = old; | ||||
act_delta = refs; | act_delta = refs; | ||||
if ((old.flags & PGA_REFERENCED) != 0) { | if ((old.flags & PGA_REFERENCED) != 0) { | ||||
new.flags &= ~PGA_REFERENCED; | new.flags &= ~PGA_REFERENCED; | ||||
▲ Show 20 Lines • Show All 1,106 Lines • Show Last 20 Lines |
I guess this is the only case where we can end up with a bogus ps_delta. It should be quite rare.
The assignment should go here, not at the top of the loop. We only break from the loop when the atomic_fcmpset at the end succeeds. In one iteration we might set ps_delta to a nonzero value, fail the update, and then exit the loop through this case, in which case ps_delta will be left equal to the old and now-incorrect value.