diff options
author | alc <alc@FreeBSD.org> | 2004-02-14 08:54:37 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-02-14 08:54:37 +0000 |
commit | 86e8aa4dc7b861b130e40a2780655661148c7444 (patch) | |
tree | b2d56f33b4b2c631809b63f778bf3d131861f44b | |
parent | 8a8ff72cd09d6aea31945e1d0eb0937e6130f486 (diff) | |
download | FreeBSD-src-86e8aa4dc7b861b130e40a2780655661148c7444.zip FreeBSD-src-86e8aa4dc7b861b130e40a2780655661148c7444.tar.gz |
- Correct a long-standing race condition in vm_page_try_to_cache() that
could result in a panic "vm_page_cache: caching a dirty page, ...":
Access to the page must be restricted or removed before calling
vm_page_cache(). This race condition is identical in nature to that
which was addressed by vm_pageout.c's revision 1.251.
- Simplify the code surrounding the fix to this same race condition
in vm_pageout.c's revision 1.251. There should be no behavioral
change. Reviewed by: tegge
MFC after: 7 days
-rw-r--r-- | sys/vm/vm_page.c | 2 | ||||
-rw-r--r-- | sys/vm/vm_pageout.c | 5 |
2 files changed, 3 insertions, 4 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 21103b3..9bc15fe 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1292,7 +1292,7 @@ vm_page_try_to_cache(vm_page_t m) (m->flags & (PG_BUSY|PG_UNMANAGED))) { return (0); } - vm_page_test_dirty(m); + pmap_remove_all(m); if (m->dirty) return (0); vm_page_cache(m); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index f807b77..05f1d5f 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -801,8 +801,7 @@ rescan0: * far as the VM code knows, any partially dirty pages are * fully dirty. */ - if (m->dirty == 0) { - vm_page_test_dirty(m); + if (m->dirty == 0 && !pmap_is_modified(m)) { /* * Avoid a race condition: Unless write access is * removed from the page, another processor could @@ -816,7 +815,7 @@ rescan0: * to the page, removing all access will be cheaper * overall. */ - if (m->dirty == 0 && (m->flags & PG_WRITEABLE) != 0) + if ((m->flags & PG_WRITEABLE) != 0) pmap_remove_all(m); } else { vm_page_dirty(m); |