Date: Thu, 29 Aug 2013 12:41:32 -0500 From: Alan Cox <alc@rice.edu> To: mips@freebsd.org Cc: Alan Cox <alc@rice.edu> Subject: pmap patch Message-ID: <521F87CC.9050205@rice.edu>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------030709000804010206080405 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Can folks here please test the attached patch against HEAD? This patch implements the new pmap_advise() function for MIPS. Alan --------------030709000804010206080405 Content-Type: text/plain; charset=ISO-8859-15; name="mips_pmap_advise.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="mips_pmap_advise.patch" Index: mips/mips/pmap.c =================================================================== --- mips/mips/pmap.c (revision 255028) +++ mips/mips/pmap.c (working copy) @@ -2919,6 +2919,85 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr 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); } /* --------------030709000804010206080405--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?521F87CC.9050205>