Date: Sat, 16 Jun 2012 18:56:19 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r237168 - in head/sys: amd64/include arm/include i386/include ia64/include mips/include powerpc/include sparc64/include vm Message-ID: <201206161856.q5GIuJqv060425@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206161856.q5GIuJqv060425>