From owner-svn-src-head@FreeBSD.ORG Sun Oct 7 18:07:46 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4C041106564A; Sun, 7 Oct 2012 18:07:46 +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 1D84B8FC08; Sun, 7 Oct 2012 18:07:46 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q97I7jMo044929; Sun, 7 Oct 2012 18:07:45 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q97I7jCM044927; Sun, 7 Oct 2012 18:07:45 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201210071807.q97I7jCM044927@svn.freebsd.org> From: Alan Cox Date: Sun, 7 Oct 2012 18:07:45 +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: r241313 - head/sys/mips/mips 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, 07 Oct 2012 18:07:46 -0000 Author: alc Date: Sun Oct 7 18:07:45 2012 New Revision: 241313 URL: http://svn.freebsd.org/changeset/base/241313 Log: Optimize the TLB invalidations performed by pmap_protect(). Use the new range-based invalidation function instead of performing per-page invalidations. Don't bother invalidating mappings that don't have PTE_D set, since they don't allow write access. Modified: head/sys/mips/mips/pmap.c Modified: head/sys/mips/mips/pmap.c ============================================================================== --- head/sys/mips/mips/pmap.c Sun Oct 7 17:48:38 2012 (r241312) +++ head/sys/mips/mips/pmap.c Sun Oct 7 18:07:45 2012 (r241313) @@ -1913,9 +1913,11 @@ pmap_remove_all(vm_page_t m) void pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) { - pt_entry_t *pte; + pt_entry_t pbits, *pte; pd_entry_t *pde, *pdpe; - vm_offset_t va_next; + vm_offset_t va, va_next; + vm_paddr_t pa; + vm_page_t m; if ((prot & VM_PROT_READ) == VM_PROT_NONE) { pmap_remove(pmap, sva, eva); @@ -1927,10 +1929,6 @@ pmap_protect(pmap_t pmap, vm_offset_t sv rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); for (; sva < eva; sva = va_next) { - pt_entry_t pbits; - vm_page_t m; - vm_paddr_t pa; - pdpe = pmap_segmap(pmap, sva); #ifdef __mips_n64 if (*pdpe == 0) { @@ -1947,29 +1945,52 @@ pmap_protect(pmap_t pmap, vm_offset_t sv pde = pmap_pdpe_to_pde(pdpe, sva); if (*pde == NULL) continue; + + /* + * Limit our scan to either the end of the va represented + * by the current page table page, or to the end of the + * range being write protected. + */ if (va_next > eva) va_next = eva; + va = va_next; for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++, - sva += PAGE_SIZE) { - - /* Skip invalid PTEs */ - if (!pte_test(pte, PTE_V)) - continue; + sva += PAGE_SIZE) { pbits = *pte; - if (pte_test(&pbits, PTE_MANAGED | PTE_D)) { - pa = TLBLO_PTE_TO_PA(pbits); - m = PHYS_TO_VM_PAGE(pa); - vm_page_dirty(m); + if (!pte_test(&pbits, PTE_V) || pte_test(&pbits, + PTE_RO)) { + if (va != va_next) { + pmap_invalidate_range(pmap, va, sva); + va = va_next; + } + continue; } - pte_clear(&pbits, PTE_D); pte_set(&pbits, PTE_RO); - - if (pbits != *pte) { - *pte = pbits; - pmap_update_page(pmap, sva, pbits); + if (pte_test(&pbits, PTE_D)) { + pte_clear(&pbits, PTE_D); + if (pte_test(&pbits, PTE_MANAGED)) { + pa = TLBLO_PTE_TO_PA(pbits); + m = PHYS_TO_VM_PAGE(pa); + vm_page_dirty(m); + } + if (va == va_next) + va = sva; + } else { + /* + * Unless PTE_D is set, any TLB entries + * mapping "sva" don't allow write access, so + * they needn't be invalidated. + */ + if (va != va_next) { + pmap_invalidate_range(pmap, va, sva); + va = va_next; + } } + *pte = pbits; } + if (va != va_next) + pmap_invalidate_range(pmap, va, sva); } rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pmap);