From owner-svn-src-head@FreeBSD.ORG Sat Aug 31 16:21:14 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 0288390C; Sat, 31 Aug 2013 16:21:14 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id CAC962991; Sat, 31 Aug 2013 16:21:13 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7VGLD4F079088; Sat, 31 Aug 2013 16:21:13 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7VGLDdM079087; Sat, 31 Aug 2013 16:21:13 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201308311621.r7VGLDdM079087@svn.freebsd.org> From: Alan Cox Date: Sat, 31 Aug 2013 16:21:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r255098 - head/sys/mips/mips X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 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: Sat, 31 Aug 2013 16:21:14 -0000 Author: alc Date: Sat Aug 31 16:21:13 2013 New Revision: 255098 URL: http://svnweb.freebsd.org/changeset/base/255098 Log: Implement pmap_advise(). Modified: head/sys/mips/mips/pmap.c Modified: head/sys/mips/mips/pmap.c ============================================================================== --- head/sys/mips/mips/pmap.c Sat Aug 31 15:40:15 2013 (r255097) +++ head/sys/mips/mips/pmap.c Sat Aug 31 16:21:13 2013 (r255098) @@ -2914,11 +2914,92 @@ pmap_is_prefaultable(pmap_t pmap, vm_off } /* - * This function is advisory. + * Apply the given advice to the specified range of addresses within the + * given pmap. Depending on the advice, clear the referenced and/or + * modified flags in each mapping and set the mapped page's dirty field. */ void pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice) { + pd_entry_t *pde, *pdpe; + pt_entry_t *pte; + vm_offset_t va, va_next; + vm_paddr_t pa; + vm_page_t m; + + if (advice != MADV_DONTNEED && advice != MADV_FREE) + return; + rw_wlock(&pvh_global_lock); + PMAP_LOCK(pmap); + for (; sva < eva; sva = va_next) { + pdpe = pmap_segmap(pmap, sva); +#ifdef __mips_n64 + if (*pdpe == 0) { + va_next = (sva + NBSEG) & ~SEGMASK; + if (va_next < sva) + va_next = eva; + continue; + } +#endif + va_next = (sva + NBPDR) & ~PDRMASK; + if (va_next < sva) + va_next = eva; + + 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) { + if (!pte_test(pte, PTE_MANAGED | PTE_V)) { + if (va != va_next) { + pmap_invalidate_range(pmap, va, sva); + va = va_next; + } + continue; + } + pa = TLBLO_PTE_TO_PA(*pte); + m = PHYS_TO_VM_PAGE(pa); + m->md.pv_flags &= ~PV_TABLE_REF; + if (pte_test(pte, PTE_D)) { + if (advice == MADV_DONTNEED) { + /* + * Future calls to pmap_is_modified() + * can be avoided by making the page + * dirty now. + */ + vm_page_dirty(m); + } else { + pte_clear(pte, PTE_D); + 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; + } + } + } + if (va != va_next) + pmap_invalidate_range(pmap, va, sva); + } + rw_wunlock(&pvh_global_lock); + PMAP_UNLOCK(pmap); } /*