summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-11-05 06:24:05 +0000
committeralc <alc@FreeBSD.org>2004-11-05 06:24:05 +0000
commitcc2178b9c838dd024b16bf677a64e9c291b6fd35 (patch)
tree0c04838a0c8e723f9019b4243a0c5486ba72a2e4 /sys/vm
parent96eb8f832a1dfbaf14980db6bc256d7c8f95f623 (diff)
downloadFreeBSD-src-cc2178b9c838dd024b16bf677a64e9c291b6fd35.zip
FreeBSD-src-cc2178b9c838dd024b16bf677a64e9c291b6fd35.tar.gz
During traversal of the inactive queue, try locking the page's containing
object before accessing the page's flags or the object's reference count.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_pageout.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index cfb9eab..7b199c8 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -728,6 +728,7 @@ rescan0:
}
next = TAILQ_NEXT(m, pageq);
+ object = m->object;
/*
* skip marker pages
@@ -747,7 +748,12 @@ rescan0:
* Don't mess with busy pages, keep in the front of the
* queue, most likely are being paged out.
*/
+ if (!VM_OBJECT_TRYLOCK(object)) {
+ addl_page_shortage++;
+ continue;
+ }
if (m->busy || (m->flags & PG_BUSY)) {
+ VM_OBJECT_UNLOCK(object);
addl_page_shortage++;
continue;
}
@@ -756,7 +762,7 @@ rescan0:
* If the object is not being used, we ignore previous
* references.
*/
- if (m->object->ref_count == 0) {
+ if (object->ref_count == 0) {
vm_page_flag_clear(m, PG_REFERENCED);
pmap_clear_reference(m);
@@ -772,6 +778,7 @@ rescan0:
} else if (((m->flags & PG_REFERENCED) == 0) &&
(actcount = pmap_ts_referenced(m))) {
vm_page_activate(m);
+ VM_OBJECT_UNLOCK(object);
m->act_count += (actcount + ACT_ADVANCE);
continue;
}
@@ -786,6 +793,7 @@ rescan0:
vm_page_flag_clear(m, PG_REFERENCED);
actcount = pmap_ts_referenced(m);
vm_page_activate(m);
+ VM_OBJECT_UNLOCK(object);
m->act_count += (actcount + ACT_ADVANCE + 1);
continue;
}
@@ -816,9 +824,6 @@ rescan0:
vm_page_dirty(m);
}
- object = m->object;
- if (!VM_OBJECT_TRYLOCK(object))
- continue;
if (m->valid == 0) {
/*
* Invalid pages can be easily freed
OpenPOWER on IntegriCloud