diff options
author | alc <alc@FreeBSD.org> | 2004-10-27 18:29:17 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-10-27 18:29:17 +0000 |
commit | ce02afb50053c051ed2f43b7135a4d361d01c2d5 (patch) | |
tree | 92090b368a1fe724a8eb98fe87f45e389f54b0c3 /sys/vm | |
parent | 7f88af1f93599792d9c99ff21dcb247e6c3c729d (diff) | |
download | FreeBSD-src-ce02afb50053c051ed2f43b7135a4d361d01c2d5.zip FreeBSD-src-ce02afb50053c051ed2f43b7135a4d361d01c2d5.tar.gz |
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.
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_pageout.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 412c430..0e52be2 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1018,12 +1018,19 @@ unlock_and_continue: ("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 @@ unlock_and_continue: * 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 @@ unlock_and_continue: * 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 @@ unlock_and_continue: vm_pageq_requeue(m); } } + VM_OBJECT_UNLOCK(object); m = next; } |