svn commit: r279135 - user/nwhitehorn/ppc64-pmap-rework/ps3

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Feb 22 02:49:29 UTC 2015


Author: nwhitehorn
Date: Sun Feb 22 02:49:27 2015
New Revision: 279135
URL: https://svnweb.freebsd.org/changeset/base/279135

Log:
  The fact that our PMAP code now can run in parallel has exposed the fact
  that the PS3 hypervisor's page table code does not have such capabilities.
  Slap a lock on all interactions with it.
  
  This fixes occasional lockups presumably caused by conflicting TLB
  invalidations.

Modified:
  user/nwhitehorn/ppc64-pmap-rework/ps3/mmu_ps3.c

Modified: user/nwhitehorn/ppc64-pmap-rework/ps3/mmu_ps3.c
==============================================================================
--- user/nwhitehorn/ppc64-pmap-rework/ps3/mmu_ps3.c	Sun Feb 22 02:16:24 2015	(r279134)
+++ user/nwhitehorn/ppc64-pmap-rework/ps3/mmu_ps3.c	Sun Feb 22 02:49:27 2015	(r279135)
@@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
-#include <sys/rwlock.h>
 #include <sys/vmmeter.h>
 
 #include <vm/vm.h>
@@ -88,14 +87,14 @@ static mmu_method_t mps3_methods[] = {
 
 MMU_DEF_INHERIT(ps3_mmu, "mmu_ps3", mps3_methods, 0, oea64_mmu);
 
-static struct rwlock mps3_eviction_lock;
+static struct mtx mps3_table_lock;
 
 static void
 mps3_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
 {
 	uint64_t final_pteg_count;
 
-	rw_init(&mps3_eviction_lock, "pte eviction");
+	mtx_init(&mps3_table_lock, "page table", NULL, MTX_DEF);
 
 	moea64_early_bootstrap(mmup, kernelstart, kernelend);
 
@@ -150,7 +149,7 @@ mps3_cpu_bootstrap(mmu_t mmup, int ap)
 }
 
 static int64_t
-mps3_pte_synch(mmu_t mmu, struct pvo_entry *pvo)
+mps3_pte_synch_locked(struct pvo_entry *pvo)
 {
 	uint64_t halfbucket[4], rcbits;
 	
@@ -168,7 +167,7 @@ mps3_pte_synch(mmu_t mmu, struct pvo_ent
 		return (-1);
 
 	/*
-	 * rcbits contains the low 12 bits of each PTEs 2nd part,
+	 * rcbits contains the low 12 bits of each PTE's 2nd part,
 	 * spaced at 16-bit intervals
 	 */
 
@@ -177,16 +176,28 @@ mps3_pte_synch(mmu_t mmu, struct pvo_ent
 }
 
 static int64_t
+mps3_pte_synch(mmu_t mmu, struct pvo_entry *pvo)
+{
+	int64_t retval;
+
+	mtx_lock(&mps3_table_lock);
+	retval = mps3_pte_synch_locked(pvo);
+	mtx_unlock(&mps3_table_lock);
+
+	return (retval);
+}
+
+static int64_t
 mps3_pte_clear(mmu_t mmu, struct pvo_entry *pvo, uint64_t ptebit)
 {
 	int64_t refchg;
 	struct lpte pte;
 
-	rw_rlock(&mps3_eviction_lock);
+	mtx_lock(&mps3_table_lock);
 
-	refchg = mps3_pte_synch(mmu, pvo);
+	refchg = mps3_pte_synch_locked(pvo);
 	if (refchg < 0) {
-		rw_runlock(&mps3_eviction_lock);
+		mtx_unlock(&mps3_table_lock);
 		return (refchg);
 	}
 
@@ -197,7 +208,7 @@ mps3_pte_clear(mmu_t mmu, struct pvo_ent
 	/* XXX: race on RC bits between write and sync. Anything to do? */
 	lv1_write_htab_entry(mps3_vas_id, pvo->pvo_pte.slot, pte.pte_hi,
 	    pte.pte_lo);
-	rw_runlock(&mps3_eviction_lock);
+	mtx_unlock(&mps3_table_lock);
 
 	return (refchg);
 }
@@ -207,16 +218,16 @@ mps3_pte_unset(mmu_t mmu, struct pvo_ent
 {
 	int64_t refchg;
 
-	rw_rlock(&mps3_eviction_lock);
-	refchg = mps3_pte_synch(mmu, pvo);
+	mtx_lock(&mps3_table_lock);
+	refchg = mps3_pte_synch_locked(pvo);
 	if (refchg < 0) {
 		moea64_pte_overflow--;
-		rw_runlock(&mps3_eviction_lock);
+		mtx_unlock(&mps3_table_lock);
 		return (-1);
 	}
 	/* XXX: race on RC bits between unset and sync. Anything to do? */
 	lv1_write_htab_entry(mps3_vas_id, pvo->pvo_pte.slot, 0, 0);
-	rw_runlock(&mps3_eviction_lock);
+	mtx_unlock(&mps3_table_lock);
 	moea64_pte_valid--;
 
 	return (refchg & (LPTE_REF | LPTE_CHG));
@@ -239,11 +250,11 @@ mps3_pte_insert(mmu_t mmu, struct pvo_en
 	moea64_pte_from_pvo(pvo, &pte);
 	evicted.pte_hi = 0;
 	PTESYNC();
-	rw_wlock(&mps3_eviction_lock);
+	mtx_lock(&mps3_table_lock);
 	result = lv1_insert_htab_entry(mps3_vas_id, pvo->pvo_pte.slot,
 	    pte.pte_hi, pte.pte_lo, LPTE_LOCKED | LPTE_WIRED, 0,
 	    &index, &evicted.pte_hi, &evicted.pte_lo);
-	rw_wunlock(&mps3_eviction_lock);
+	mtx_unlock(&mps3_table_lock);
 
 	if (result != 0) {
 		/* No freeable slots in either PTEG? We're hosed. */


More information about the svn-src-user mailing list