Author: alc
Date: Sat Jun 16 18:56:19 2012
New Revision: 237168
URL: http://svn.freebsd.org/changeset/base/237168

Log:
  The page flag PGA_WRITEABLE is set and cleared exclusively by the pmap
  layer, but it is read directly by the MI VM layer.  This change introduces
  pmap_page_is_write_mapped() in order to completely encapsulate all direct
  access to PGA_WRITEABLE in the pmap layer.
  
  Aesthetics aside, I am making this change because amd64 will likely begin
  using an alternative method to track write mappings, and having
  pmap_page_is_write_mapped() in place allows me to make such a change
  without further modification to the MI VM layer.
  
  As an added bonus, tidy up some nearby comments concerning page flags.
  
  Reviewed by:  kib
  MFC after:    6 weeks

Modified:
  head/sys/amd64/include/pmap.h
  head/sys/arm/include/pmap.h
  head/sys/i386/include/pmap.h
  head/sys/ia64/include/pmap.h
  head/sys/mips/include/pmap.h
  head/sys/powerpc/include/pmap.h
  head/sys/sparc64/include/pmap.h
  head/sys/vm/pmap.h
  head/sys/vm/swap_pager.c
  head/sys/vm/vm_page.c
  head/sys/vm/vm_page.h
  head/sys/vm/vm_pageout.c
  head/sys/vm/vnode_pager.c

Modified: head/sys/amd64/include/pmap.h
==============================================================================
--- head/sys/amd64/include/pmap.h       Sat Jun 16 18:37:54 2012        
(r237167)
+++ head/sys/amd64/include/pmap.h       Sat Jun 16 18:56:19 2012        
(r237168)
@@ -309,6 +309,7 @@ extern vm_offset_t virtual_avail;
 extern vm_offset_t virtual_end;
 
 #define        pmap_page_get_memattr(m)        ((vm_memattr_t)(m)->md.pat_mode)
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
 #define        pmap_unmapbios(va, sz)  pmap_unmapdev((va), (sz))
 
 void   pmap_bootstrap(vm_paddr_t *);

Modified: head/sys/arm/include/pmap.h
==============================================================================
--- head/sys/arm/include/pmap.h Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/arm/include/pmap.h Sat Jun 16 18:56:19 2012        (r237168)
@@ -78,6 +78,7 @@
 
 #define        pmap_page_get_memattr(m)        VM_MEMATTR_DEFAULT
 #define        pmap_page_is_mapped(m)  (!TAILQ_EMPTY(&(m)->md.pv_list))
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
 #define        pmap_page_set_memattr(m, ma)    (void)0
 
 /*

Modified: head/sys/i386/include/pmap.h
==============================================================================
--- head/sys/i386/include/pmap.h        Sat Jun 16 18:37:54 2012        
(r237167)
+++ head/sys/i386/include/pmap.h        Sat Jun 16 18:56:19 2012        
(r237168)
@@ -498,6 +498,7 @@ extern vm_offset_t virtual_avail;
 extern vm_offset_t virtual_end;
 
 #define        pmap_page_get_memattr(m)        ((vm_memattr_t)(m)->md.pat_mode)
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
 #define        pmap_unmapbios(va, sz)  pmap_unmapdev((va), (sz))
 
 /*

Modified: head/sys/ia64/include/pmap.h
==============================================================================
--- head/sys/ia64/include/pmap.h        Sat Jun 16 18:37:54 2012        
(r237167)
+++ head/sys/ia64/include/pmap.h        Sat Jun 16 18:56:19 2012        
(r237168)
@@ -118,6 +118,7 @@ extern int pmap_vhpt_log2size;
 
 #define        pmap_page_get_memattr(m)        ((m)->md.memattr)
 #define        pmap_page_is_mapped(m)  (!TAILQ_EMPTY(&(m)->md.pv_list))
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
 #define        pmap_mapbios(pa, sz)    pmap_mapdev(pa, sz)
 #define        pmap_unmapbios(va, sz)  pmap_unmapdev(va, sz)
 

Modified: head/sys/mips/include/pmap.h
==============================================================================
--- head/sys/mips/include/pmap.h        Sat Jun 16 18:37:54 2012        
(r237167)
+++ head/sys/mips/include/pmap.h        Sat Jun 16 18:56:19 2012        
(r237168)
@@ -151,6 +151,7 @@ extern vm_paddr_t dump_avail[PHYS_AVAIL_
 
 #define        pmap_page_get_memattr(m)        VM_MEMATTR_DEFAULT
 #define        pmap_page_is_mapped(m)  (!TAILQ_EMPTY(&(m)->md.pv_list))
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
 #define        pmap_page_set_memattr(m, ma)    (void)0
 
 void pmap_bootstrap(void);

Modified: head/sys/powerpc/include/pmap.h
==============================================================================
--- head/sys/powerpc/include/pmap.h     Sat Jun 16 18:37:54 2012        
(r237167)
+++ head/sys/powerpc/include/pmap.h     Sat Jun 16 18:56:19 2012        
(r237168)
@@ -223,6 +223,8 @@ extern      struct pmap kernel_pmap_store;
 #define        PMAP_TRYLOCK(pmap)      mtx_trylock(&(pmap)->pm_mtx)
 #define        PMAP_UNLOCK(pmap)       mtx_unlock(&(pmap)->pm_mtx)
 
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
+
 void           pmap_bootstrap(vm_offset_t, vm_offset_t);
 void           pmap_kenter(vm_offset_t va, vm_paddr_t pa);
 void           pmap_kenter_attr(vm_offset_t va, vm_offset_t pa, vm_memattr_t);

Modified: head/sys/sparc64/include/pmap.h
==============================================================================
--- head/sys/sparc64/include/pmap.h     Sat Jun 16 18:37:54 2012        
(r237167)
+++ head/sys/sparc64/include/pmap.h     Sat Jun 16 18:56:19 2012        
(r237168)
@@ -80,6 +80,7 @@ struct pmap {
 #define        PMAP_UNLOCK(pmap)       mtx_unlock(&(pmap)->pm_mtx)
 
 #define        pmap_page_get_memattr(m)        VM_MEMATTR_DEFAULT
+#define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) 
!= 0)
 #define        pmap_page_set_memattr(m, ma)    (void)0
 
 void   pmap_bootstrap(u_int cpu_impl);

Modified: head/sys/vm/pmap.h
==============================================================================
--- head/sys/vm/pmap.h  Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/vm/pmap.h  Sat Jun 16 18:56:19 2012        (r237168)
@@ -80,10 +80,11 @@ struct pmap_statistics {
 typedef struct pmap_statistics *pmap_statistics_t;
 
 /*
- * Each machine dependent implementation is expected to provide:
+ * Each machine-dependent implementation is required to provide:
  *
  * vm_memattr_t        pmap_page_get_memattr(vm_page_t);
  * boolean_t   pmap_page_is_mapped(vm_page_t);
+ * boolean_t   pmap_page_is_write_mapped(vm_page_t);
  * void                pmap_page_set_memattr(vm_page_t, vm_memattr_t);
  */
 #include <machine/pmap.h>

Modified: head/sys/vm/swap_pager.c
==============================================================================
--- head/sys/vm/swap_pager.c    Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/vm/swap_pager.c    Sat Jun 16 18:56:19 2012        (r237168)
@@ -1593,7 +1593,7 @@ swp_pager_async_iodone(struct buf *bp)
                         * status, then finish the I/O ( which decrements the 
                         * busy count and possibly wakes waiter's up ).
                         */
-                       KASSERT((m->aflags & PGA_WRITEABLE) == 0,
+                       KASSERT(!pmap_page_is_write_mapped(m),
                            ("swp_pager_async_iodone: page %p is not write"
                            " protected", m));
                        vm_page_undirty(m);

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c       Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/vm/vm_page.c       Sat Jun 16 18:56:19 2012        (r237168)
@@ -930,7 +930,7 @@ vm_page_insert(vm_page_t m, vm_object_t 
         * Since we are inserting a new and possibly dirty page,
         * update the object's OBJ_MIGHTBEDIRTY flag.
         */
-       if (m->aflags & PGA_WRITEABLE)
+       if (pmap_page_is_write_mapped(m))
                vm_object_set_writeable_dirty(object);
 }
 
@@ -2675,11 +2675,11 @@ vm_page_clear_dirty_mask(vm_page_t m, vm
 
        /*
         * If the object is locked and the page is neither VPO_BUSY nor
-        * PGA_WRITEABLE, then the page's dirty field cannot possibly be
+        * write mapped, then the page's dirty field cannot possibly be
         * set by a concurrent pmap operation.
         */
        VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
-       if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0)
+       if ((m->oflags & VPO_BUSY) == 0 && !pmap_page_is_write_mapped(m))
                m->dirty &= ~pagebits;
        else {
                /*

Modified: head/sys/vm/vm_page.h
==============================================================================
--- head/sys/vm/vm_page.h       Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/vm/vm_page.h       Sat Jun 16 18:56:19 2012        (r237168)
@@ -237,20 +237,22 @@ extern struct vpglocks pa_lock[];
 #endif
 
 #define        vm_page_queue_free_mtx  vm_page_queue_free_lock.data
+
 /*
  * These are the flags defined for vm_page.
  *
- * aflags are updated by atomic accesses. Use the vm_page_aflag_set()
+ * aflags are updated by atomic accesses.  Use the vm_page_aflag_set()
  * and vm_page_aflag_clear() functions to set and clear the flags.
  *
  * PGA_REFERENCED may be cleared only if the object containing the page is
- * locked.
+ * locked.  It is set by both the MI and MD VM layers.
  *
  * PGA_WRITEABLE is set exclusively on managed pages by pmap_enter().  When it
- * does so, the page must be VPO_BUSY.
+ * does so, the page must be VPO_BUSY.  The MI VM layer must never access this
+ * flag directly.  Instead, it should call pmap_page_is_write_mapped().
  *
  * PGA_EXECUTABLE may be set by pmap routines, and indicates that a page has
- * at least one executable mapping. It is not consumed by the VM layer.
+ * at least one executable mapping.  It is not consumed by the MI VM layer.
  */
 #define        PGA_WRITEABLE   0x01            /* page may be mapped writeable 
*/
 #define        PGA_REFERENCED  0x02            /* page has been referenced */
@@ -262,12 +264,12 @@ extern struct vpglocks pa_lock[];
  */
 #define        PG_CACHED       0x01            /* page is cached */
 #define        PG_FREE         0x02            /* page is free */
-#define        PG_FICTITIOUS   0x04            /* physical page doesn't exist 
(O) */
+#define        PG_FICTITIOUS   0x04            /* physical page doesn't exist 
*/
 #define        PG_ZERO         0x08            /* page is zeroed */
 #define        PG_MARKER       0x10            /* special queue marker page */
 #define        PG_SLAB         0x20            /* object pointer is actually a 
slab */
 #define        PG_WINATCFLS    0x40            /* flush dirty page on inactive 
q */
-#define        PG_NODUMP       0x80            /* don't include this page in 
the dump */
+#define        PG_NODUMP       0x80            /* don't include this page in a 
dump */
 
 /*
  * Misc constants.

Modified: head/sys/vm/vm_pageout.c
==============================================================================
--- head/sys/vm/vm_pageout.c    Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/vm/vm_pageout.c    Sat Jun 16 18:56:19 2012        (r237168)
@@ -503,7 +503,7 @@ vm_pageout_flush(vm_page_t *mc, int coun
                vm_page_t mt = mc[i];
 
                KASSERT(pageout_status[i] == VM_PAGER_PEND ||
-                   (mt->aflags & PGA_WRITEABLE) == 0,
+                   !pmap_page_is_write_mapped(mt),
                    ("vm_pageout_flush: page %p is not write protected", mt));
                switch (pageout_status[i]) {
                case VM_PAGER_OK:
@@ -899,7 +899,7 @@ rescan0:
                 * be updated.
                 */
                if (m->dirty != VM_PAGE_BITS_ALL &&
-                   (m->aflags & PGA_WRITEABLE) != 0) {
+                   pmap_page_is_write_mapped(m)) {
                        /*
                         * Avoid a race condition: Unless write access is
                         * removed from the page, another processor could

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c   Sat Jun 16 18:37:54 2012        (r237167)
+++ head/sys/vm/vnode_pager.c   Sat Jun 16 18:56:19 2012        (r237168)
@@ -1146,7 +1146,7 @@ vnode_pager_generic_putpages(struct vnod
                                m = ma[ncount - 1];
                                KASSERT(m->busy > 0,
                ("vnode_pager_generic_putpages: page %p is not busy", m));
-                               KASSERT((m->aflags & PGA_WRITEABLE) == 0,
+                               KASSERT(!pmap_page_is_write_mapped(m),
                ("vnode_pager_generic_putpages: page %p is not read-only", m));
                                vm_page_clear_dirty(m, pgoff, PAGE_SIZE -
                                    pgoff);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to