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