Author: alc
Date: Sat Sep 29 17:20:16 2012
New Revision: 241054
URL: http://svn.freebsd.org/changeset/base/241054

Log:
  Add support for mincore().  Specifically, this is an adaptation of the
  pmap_mincore() implementation that was added to the original arm pmap
  in r235717.

Modified:
  head/sys/arm/arm/pmap-v6.c

Modified: head/sys/arm/arm/pmap-v6.c
==============================================================================
--- head/sys/arm/arm/pmap-v6.c  Sat Sep 29 16:47:56 2012        (r241053)
+++ head/sys/arm/arm/pmap-v6.c  Sat Sep 29 17:20:16 2012        (r241054)
@@ -3462,9 +3462,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 (L2_S_WRITABLE(pte))
+               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) == 0)
+               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);
 }
 
 void
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to