summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-10-30 23:30:53 +0000
committeralc <alc@FreeBSD.org>2004-10-30 23:30:53 +0000
commit17432a99e56e3aac0424524d9bdd13da99487254 (patch)
treecd8eed6693060e48f5c64fd758a01df5edb81d82 /sys/vm
parentbfa67dd1480efe8289be522e9b8b035813a287df (diff)
downloadFreeBSD-src-17432a99e56e3aac0424524d9bdd13da99487254.zip
FreeBSD-src-17432a99e56e3aac0424524d9bdd13da99487254.tar.gz
During traversal of the active queue by vm_pageout_page_stats(), try
locking the page's containing object before accessing the page's flags.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_pageout.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 9018a73..3d21c1f 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1241,6 +1241,7 @@ unlock_and_continue:
static void
vm_pageout_page_stats()
{
+ vm_object_t object;
vm_page_t m,next;
int pcount,tpcount; /* Number of pages to check */
static int fullintervalcount = 0;
@@ -1272,12 +1273,20 @@ vm_pageout_page_stats()
("vm_pageout_page_stats: page %p isn't active", m));
next = TAILQ_NEXT(m, pageq);
+ object = m->object;
+ if (!VM_OBJECT_TRYLOCK(object)) {
+ vm_pageq_requeue(m);
+ m = next;
+ 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;
@@ -1313,7 +1322,7 @@ vm_pageout_page_stats()
vm_pageq_requeue(m);
}
}
-
+ VM_OBJECT_UNLOCK(object);
m = next;
}
}
OpenPOWER on IntegriCloud