From owner-svn-src-head@FreeBSD.ORG Sun Jul 19 21:40:19 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D63D6106564A; Sun, 19 Jul 2009 21:40:19 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C48858FC20; Sun, 19 Jul 2009 21:40:19 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n6JLeJ5x054554; Sun, 19 Jul 2009 21:40:19 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n6JLeJ5X054549; Sun, 19 Jul 2009 21:40:19 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <200907192140.n6JLeJ5X054549@svn.freebsd.org> From: Alan Cox Date: Sun, 19 Jul 2009 21:40:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195774 - in head/sys: amd64/amd64 i386/i386 i386/xen vm X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 19 Jul 2009 21:40:20 -0000 Author: alc Date: Sun Jul 19 21:40:19 2009 New Revision: 195774 URL: http://svn.freebsd.org/changeset/base/195774 Log: Change the handling of fictitious pages by pmap_page_set_memattr() on amd64 and i386. Essentially, fictitious pages provide a mechanism for creating aliases for either normal or device-backed pages. Therefore, pmap_page_set_memattr() on a fictitious page needn't update the direct map or flush the cache. Such actions are the responsibility of the "primary" instance of the page or the device driver that "owns" the physical address. For example, these actions are already performed by pmap_mapdev(). The device pager needn't restore the memory attributes on a fictitious page before releasing it. It's now pointless. Add pmap_page_set_memattr() to the Xen pmap. Approved by: re (kib) Modified: head/sys/amd64/amd64/pmap.c head/sys/i386/i386/pmap.c head/sys/i386/xen/pmap.c head/sys/vm/device_pager.c Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Sun Jul 19 20:25:59 2009 (r195773) +++ head/sys/amd64/amd64/pmap.c Sun Jul 19 21:40:19 2009 (r195774) @@ -4381,9 +4381,12 @@ pmap_page_set_memattr(vm_page_t m, vm_me m->md.pat_mode = ma; /* - * Update the direct mapping and flush the cache. + * If "m" is a normal page, update its direct mapping. This update + * can be relied upon to perform any cache operations that are + * required for data coherence. */ - if (pmap_change_attr(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)), PAGE_SIZE, + if ((m->flags & PG_FICTITIOUS) == 0 && + pmap_change_attr(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)), PAGE_SIZE, m->md.pat_mode)) panic("memory attribute change on the direct map failed"); } Modified: head/sys/i386/i386/pmap.c ============================================================================== --- head/sys/i386/i386/pmap.c Sun Jul 19 20:25:59 2009 (r195773) +++ head/sys/i386/i386/pmap.c Sun Jul 19 21:40:19 2009 (r195774) @@ -4466,12 +4466,13 @@ pmap_page_set_memattr(vm_page_t m, vm_me m->md.pat_mode = ma; /* - * Flush CPU caches to make sure any data isn't cached that shouldn't - * be, etc. + * If "m" is a normal page, flush it from the cache. */ - /* If "Self Snoop" is supported, do nothing. */ - if (!(cpu_feature & CPUID_SS)) - pmap_invalidate_cache(); + if ((m->flags & PG_FICTITIOUS) == 0) { + /* If "Self Snoop" is supported, do nothing. */ + if (!(cpu_feature & CPUID_SS)) + pmap_invalidate_cache(); + } } int Modified: head/sys/i386/xen/pmap.c ============================================================================== --- head/sys/i386/xen/pmap.c Sun Jul 19 20:25:59 2009 (r195773) +++ head/sys/i386/xen/pmap.c Sun Jul 19 21:40:19 2009 (r195774) @@ -3921,6 +3921,25 @@ pmap_unmapdev(vm_offset_t va, vm_size_t kmem_free(kernel_map, base, size); } +/* + * Sets the memory attribute for the specified page. + */ +void +pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) +{ + + m->md.pat_mode = ma; + + /* + * If "m" is a normal page, flush it from the cache. + */ + if ((m->flags & PG_FICTITIOUS) == 0) { + /* If "Self Snoop" is supported, do nothing. */ + if (!(cpu_feature & CPUID_SS)) + pmap_invalidate_cache(); + } +} + int pmap_change_attr(va, size, mode) vm_offset_t va; Modified: head/sys/vm/device_pager.c ============================================================================== --- head/sys/vm/device_pager.c Sun Jul 19 20:25:59 2009 (r195773) +++ head/sys/vm/device_pager.c Sun Jul 19 21:40:19 2009 (r195774) @@ -305,7 +305,8 @@ dev_pager_haspage(object, pindex, before /* * Create a fictitious page with the specified physical address and memory - * attribute. + * attribute. The memory attribute is the only the machine-dependent aspect + * of a fictitious page that must be initialized. */ static vm_page_t dev_pager_getfake(vm_paddr_t paddr, vm_memattr_t memattr) @@ -317,11 +318,9 @@ dev_pager_getfake(vm_paddr_t paddr, vm_m /* Fictitious pages don't use "segind". */ m->flags = PG_FICTITIOUS; /* Fictitious pages don't use "order" or "pool". */ - pmap_page_init(m); m->oflags = VPO_BUSY; m->wire_count = 1; - if (memattr != VM_MEMATTR_DEFAULT) - pmap_page_set_memattr(m, memattr); + pmap_page_set_memattr(m, memattr); return (m); } @@ -334,9 +333,6 @@ dev_pager_putfake(vm_page_t m) if (!(m->flags & PG_FICTITIOUS)) panic("dev_pager_putfake: bad page"); - /* Restore the default memory attribute to "phys_addr". */ - if (pmap_page_get_memattr(m) != VM_MEMATTR_DEFAULT) - pmap_page_set_memattr(m, VM_MEMATTR_DEFAULT); uma_zfree(fakepg_zone, m); } @@ -350,10 +346,6 @@ dev_pager_updatefake(vm_page_t m, vm_pad if (!(m->flags & PG_FICTITIOUS)) panic("dev_pager_updatefake: bad page"); - /* Restore the default memory attribute before changing "phys_addr". */ - if (pmap_page_get_memattr(m) != VM_MEMATTR_DEFAULT) - pmap_page_set_memattr(m, VM_MEMATTR_DEFAULT); m->phys_addr = paddr; - if (memattr != VM_MEMATTR_DEFAULT) - pmap_page_set_memattr(m, memattr); + pmap_page_set_memattr(m, memattr); }