diff options
author | alc <alc@FreeBSD.org> | 2004-10-30 23:30:53 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-10-30 23:30:53 +0000 |
commit | 17432a99e56e3aac0424524d9bdd13da99487254 (patch) | |
tree | cd8eed6693060e48f5c64fd758a01df5edb81d82 /sys/vm/vm_pageout.c | |
parent | bfa67dd1480efe8289be522e9b8b035813a287df (diff) | |
download | FreeBSD-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/vm_pageout.c')
-rw-r--r-- | sys/vm/vm_pageout.c | 11 |
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; } } |