Skip site navigation (1)Skip section navigation (2)
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>