Author: nwhitehorn
Date: Thu Apr 26 14:00:29 2012
New Revision: 234707
URL: http://svn.freebsd.org/changeset/base/234707

Log:
  MFC r234579:
  Avoid a lock order reversal in pmap_extract_and_hold() from relocking
  the page. This PMAP requires an additional lock besides the PMAP lock
  in pmap_extract_and_hold(), which vm_page_pa_tryrelock() did not release.
  
  Suggested by: kib

Modified:
  stable/9/sys/powerpc/aim/mmu_oea64.c
  stable/9/sys/vm/vm_page.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/powerpc/aim/mmu_oea64.c
==============================================================================
--- stable/9/sys/powerpc/aim/mmu_oea64.c        Thu Apr 26 13:59:00 2012        
(r234706)
+++ stable/9/sys/powerpc/aim/mmu_oea64.c        Thu Apr 26 14:00:29 2012        
(r234707)
@@ -1332,6 +1332,37 @@ moea64_extract(mmu_t mmu, pmap_t pm, vm_
  * pmap and virtual address pair if that mapping permits the given
  * protection.
  */
+
+extern int pa_tryrelock_restart;
+
+static int
+vm_page_pa_tryrelock_moea64(pmap_t pmap, vm_paddr_t pa, vm_paddr_t *locked)
+{
+       /*
+        * This is a duplicate of vm_page_pa_tryrelock(), but with proper
+        * handling of the table lock
+        */
+       vm_paddr_t lockpa;
+
+       lockpa = *locked;
+       *locked = pa;
+       if (lockpa) {
+               PA_LOCK_ASSERT(lockpa, MA_OWNED);
+               if (PA_LOCKPTR(pa) == PA_LOCKPTR(lockpa))
+                       return (0);
+               PA_UNLOCK(lockpa);
+       }
+       if (PA_TRYLOCK(pa))
+               return (0);
+       UNLOCK_TABLE_RD();
+       PMAP_UNLOCK(pmap);
+       atomic_add_int(&pa_tryrelock_restart, 1);
+       PA_LOCK(pa);
+       LOCK_TABLE_RD();
+       PMAP_LOCK(pmap);
+       return (EAGAIN);
+}
+
 vm_page_t
 moea64_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_prot_t prot)
 {
@@ -1348,7 +1379,7 @@ retry:
        if (pvo != NULL && (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) &&
            ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) == LPTE_RW ||
             (prot & VM_PROT_WRITE) == 0)) {
-               if (vm_page_pa_tryrelock(pmap,
+               if (vm_page_pa_tryrelock_moea64(pmap,
                        pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN, &pa))
                        goto retry;
                m = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);

Modified: stable/9/sys/vm/vm_page.c
==============================================================================
--- stable/9/sys/vm/vm_page.c   Thu Apr 26 13:59:00 2012        (r234706)
+++ stable/9/sys/vm/vm_page.c   Thu Apr 26 14:00:29 2012        (r234707)
@@ -131,7 +131,7 @@ TUNABLE_INT("vm.boot_pages", &boot_pages
 SYSCTL_INT(_vm, OID_AUTO, boot_pages, CTLFLAG_RD, &boot_pages, 0,
        "number of pages allocated for bootstrapping the VM system");
 
-static int pa_tryrelock_restart;
+int pa_tryrelock_restart;
 SYSCTL_INT(_vm, OID_AUTO, tryrelock_restart, CTLFLAG_RD,
     &pa_tryrelock_restart, 0, "Number of tryrelock restarts");
 
_______________________________________________
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