svn commit: r234707 - in stable/9/sys: powerpc/aim vm
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Thu Apr 26 14:00:30 UTC 2012
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");
More information about the svn-src-stable-9
mailing list