1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-19 10:53:58 +00:00

During traversal of the active queue, try locking the page's containing

object before accessing the page's flags or the object's reference count.
If the trylock fails, handle the page as though it is busy.
This commit is contained in:
Alan Cox 2004-10-27 18:29:17 +00:00
parent 3904b13fab
commit b08abf6cc0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136996

View File

@ -1018,12 +1018,19 @@ vm_pageout_scan(int pass)
("vm_pageout_scan: page %p isn't active", m));
next = TAILQ_NEXT(m, pageq);
object = m->object;
if (!VM_OBJECT_TRYLOCK(object)) {
vm_pageq_requeue(m);
continue;
}
/*
* Don't deactivate pages that are busy.
*/
if ((m->busy != 0) ||
(m->flags & PG_BUSY) ||
(m->hold_count != 0)) {
VM_OBJECT_UNLOCK(object);
vm_pageq_requeue(m);
m = next;
continue;
@ -1039,7 +1046,7 @@ vm_pageout_scan(int pass)
* Check to see "how much" the page has been used.
*/
actcount = 0;
if (m->object->ref_count != 0) {
if (object->ref_count != 0) {
if (m->flags & PG_REFERENCED) {
actcount += 1;
}
@ -1060,15 +1067,15 @@ vm_pageout_scan(int pass)
* Only if an object is currently being used, do we use the
* page activation count stats.
*/
if (actcount && (m->object->ref_count != 0)) {
if (actcount && (object->ref_count != 0)) {
vm_pageq_requeue(m);
} else {
m->act_count -= min(m->act_count, ACT_DECLINE);
if (vm_pageout_algorithm ||
m->object->ref_count == 0 ||
object->ref_count == 0 ||
m->act_count == 0) {
page_shortage--;
if (m->object->ref_count == 0) {
if (object->ref_count == 0) {
pmap_remove_all(m);
if (m->dirty == 0)
vm_page_cache(m);
@ -1081,6 +1088,7 @@ vm_pageout_scan(int pass)
vm_pageq_requeue(m);
}
}
VM_OBJECT_UNLOCK(object);
m = next;
}