Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Dec 2013 19:48:48 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r259190 - stable/9/sys/arm/arm
Message-ID:  <201312101948.rBAJmmOL090144@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Tue Dec 10 19:48:48 2013
New Revision: 259190
URL: http://svnweb.freebsd.org/changeset/base/259190

Log:
  Hand merge from current r235717:
  Implement pmap_mincore for arm.  Now programs using it don't cause a
  flood of console messages.
  
  Reviewed by:	alc@

Modified:
  stable/9/sys/arm/arm/pmap.c

Modified: stable/9/sys/arm/arm/pmap.c
==============================================================================
--- stable/9/sys/arm/arm/pmap.c	Tue Dec 10 19:42:35 2013	(r259189)
+++ stable/9/sys/arm/arm/pmap.c	Tue Dec 10 19:48:48 2013	(r259190)
@@ -4675,9 +4675,59 @@ pmap_remove_write(vm_page_t m)
 int
 pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
 {
-	printf("pmap_mincore()\n");
-	
-	return (0);
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	vm_page_t m;
+	int val;
+	boolean_t managed;
+
+	PMAP_LOCK(pmap);
+retry:
+	l2b = pmap_get_l2_bucket(pmap, addr);
+        if (l2b == NULL) {
+                val = 0;
+                goto out;
+        }
+	ptep = &l2b->l2b_kva[l2pte_index(addr)];
+	pte = *ptep;
+	if (!l2pte_valid(pte)) {
+		val = 0;
+		goto out;
+	}
+	val = MINCORE_INCORE;
+	if (pte & L2_S_PROT_W)
+		val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
+        managed = false;
+	pa = l2pte_pa(pte);
+        m = PHYS_TO_VM_PAGE(pa);
+        if (m != NULL && !(m->oflags & VPO_UNMANAGED))
+                managed = true;
+	if (managed) {
+		/*
+		 * The ARM pmap tries to maintain a per-mapping
+		 * reference bit.  The trouble is that it's kept in
+		 * the PV entry, not the PTE, so it's costly to access
+		 * here.  You would need to acquire the pvh global
+		 * lock, call pmap_find_pv(), and introduce a custom
+		 * version of vm_page_pa_tryrelock() that releases and
+		 * reacquires the pvh global lock.  In the end, I
+		 * doubt it's worthwhile.  This may falsely report
+		 * the given address as referenced.
+		 */
+		if ((m->md.pvh_attrs & PVF_REF) != 0)
+			val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
+	}
+	if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
+	    (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && managed) {
+		/* Ensure that "PHYS_TO_VM_PAGE(pa)->object" doesn't change. */
+		if (vm_page_pa_tryrelock(pmap, pa, locked_pa))
+			goto retry;
+	} else
+out:
+		PA_UNLOCK_COND(*locked_pa);
+	PMAP_UNLOCK(pmap);
+	return (val);
 }
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312101948.rBAJmmOL090144>