summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_page.h
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2010-05-29 17:10:45 +0000
committeralc <alc@FreeBSD.org>2010-05-29 17:10:45 +0000
commit012f4aa2016757281b9b4f9b80ca2296b66a3e92 (patch)
tree09abd6706e74dde3b422058d85e5421c74c98c91 /sys/vm/vm_page.h
parente9869620a0a829b328eecad1040fb7825c5aaf2c (diff)
downloadFreeBSD-src-012f4aa2016757281b9b4f9b80ca2296b66a3e92.zip
FreeBSD-src-012f4aa2016757281b9b4f9b80ca2296b66a3e92.tar.gz
When I pushed down the page queues lock into pmap_is_modified(), I created
an ordering dependence: A pmap operation that clears PG_WRITEABLE and calls vm_page_dirty() must perform the call first. Otherwise, pmap_is_modified() could return FALSE without acquiring the page queues lock because the page is not (currently) writeable, and the caller to pmap_is_modified() might believe that the page's dirty field is clear because it has not seen the effect of the vm_page_dirty() call. When I pushed down the page queues lock into pmap_is_modified(), I overlooked one place where this ordering dependence is violated: pmap_enter(). In a rare situation pmap_enter() can be called to replace a dirty mapping to one page with a mapping to another page. (I say rare because replacements generally occur as a result of a copy-on-write fault, and so the old page is not dirty.) This change delays clearing PG_WRITEABLE until after vm_page_dirty() has been called. Fixing the ordering dependency also makes it easy to introduce a small optimization: When pmap_enter() used to replace a mapping to one page with a mapping to another page, it freed the pv entry for the first mapping and later called the pv entry allocator for the new mapping. Now, pmap_enter() attempts to recycle the old pv entry, saving two calls to the pv entry allocator. There is no point in setting PG_WRITEABLE on unmanaged pages, so don't. Update a comment to reflect this. Tidy up the variable declarations at the start of pmap_enter().
Diffstat (limited to 'sys/vm/vm_page.h')
-rw-r--r--sys/vm/vm_page.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index fb1cfda..e8f68d2 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -219,8 +219,8 @@ extern struct vpglocks pa_lock[];
* pte mappings, nor can they be removed from their objects via
* the object, and such pages are also not on any PQ queue.
*
- * PG_WRITEABLE is set exclusively by pmap_enter(). When it does so, the page
- * must be VPO_BUSY.
+ * PG_WRITEABLE is set exclusively on managed pages by pmap_enter(). When it
+ * does so, the page must be VPO_BUSY.
*/
#define PG_CACHED 0x0001 /* page is cached */
#define PG_FREE 0x0002 /* page is free */
OpenPOWER on IntegriCloud