svn commit: r242434 - head/sys/vm
Alan Cox
alc at FreeBSD.org
Thu Nov 1 16:20:03 UTC 2012
Author: alc
Date: Thu Nov 1 16:20:02 2012
New Revision: 242434
URL: http://svn.freebsd.org/changeset/base/242434
Log:
In general, we call pmap_remove_all() before calling vm_page_cache(). So,
the call to pmap_remove_all() within vm_page_cache() is usually redundant.
This change eliminates that call to pmap_remove_all() and introduces a
call to pmap_remove_all() before vm_page_cache() in the one place where
it didn't already exist.
When iterating over a paging queue, if the object containing the current
page has a zero reference count, then the page can't have any managed
mappings. So, a call to pmap_remove_all() is pointless.
Change a panic() call in vm_page_cache() to a KASSERT().
MFC after: 6 weeks
Modified:
head/sys/vm/vm_page.c
head/sys/vm/vm_pageout.c
Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c Thu Nov 1 15:17:43 2012 (r242433)
+++ head/sys/vm/vm_page.c Thu Nov 1 16:20:02 2012 (r242434)
@@ -2277,9 +2277,9 @@ vm_page_cache(vm_page_t m)
if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) || m->busy ||
m->hold_count || m->wire_count)
panic("vm_page_cache: attempting to cache busy page");
- pmap_remove_all(m);
- if (m->dirty != 0)
- panic("vm_page_cache: page %p is dirty", m);
+ KASSERT(!pmap_page_is_mapped(m),
+ ("vm_page_cache: page %p is mapped", m));
+ KASSERT(m->dirty == 0, ("vm_page_cache: page %p is dirty", m));
if (m->valid == 0 || object->type == OBJT_DEFAULT ||
(object->type == OBJT_SWAP &&
!vm_pager_has_page(object, m->pindex, NULL, NULL))) {
Modified: head/sys/vm/vm_pageout.c
==============================================================================
--- head/sys/vm/vm_pageout.c Thu Nov 1 15:17:43 2012 (r242433)
+++ head/sys/vm/vm_pageout.c Thu Nov 1 16:20:02 2012 (r242434)
@@ -594,7 +594,7 @@ vm_pageout_launder(int queue, int tries,
continue;
}
vm_page_test_dirty(m);
- if (m->dirty == 0)
+ if (m->dirty == 0 && object->ref_count != 0)
pmap_remove_all(m);
if (m->dirty != 0) {
vm_page_unlock(m);
@@ -1059,31 +1059,16 @@ vm_pageout_scan(int pass)
}
/*
- * If the upper level VM system does not believe that the page
- * is fully dirty, but it is mapped for write access, then we
- * consult the pmap to see if the page's dirty status should
- * be updated.
+ * If the page appears to be clean at the machine-independent
+ * layer, then remove all of its mappings from the pmap in
+ * anticipation of placing it onto the cache queue. If,
+ * however, any of the page's mappings allow write access,
+ * then the page may still be modified until the last of those
+ * mappings are removed.
*/
- if (m->dirty != VM_PAGE_BITS_ALL &&
- pmap_page_is_write_mapped(m)) {
- /*
- * Avoid a race condition: Unless write access is
- * removed from the page, another processor could
- * modify it before all access is removed by the call
- * to vm_page_cache() below. If vm_page_cache() finds
- * that the page has been modified when it removes all
- * access, it panics because it cannot cache dirty
- * pages. In principle, we could eliminate just write
- * access here rather than all access. In the expected
- * case, when there are no last instant modifications
- * to the page, removing all access will be cheaper
- * overall.
- */
- if (pmap_is_modified(m))
- vm_page_dirty(m);
- else if (m->dirty == 0)
- pmap_remove_all(m);
- }
+ vm_page_test_dirty(m);
+ if (m->dirty == 0 && object->ref_count != 0)
+ pmap_remove_all(m);
if (m->valid == 0) {
/*
More information about the svn-src-head
mailing list