Date: Sun, 22 Feb 2015 02:49:28 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r279135 - user/nwhitehorn/ppc64-pmap-rework/ps3 Message-ID: <201502220249.t1M2nSoN035914@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502220249.t1M2nSoN035914>