diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-09-16 00:22:25 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-09-16 00:22:25 +0000 |
commit | 489c1437aad80456391795b153ab87e37f44680d (patch) | |
tree | 5545963fb3f01498f05522fd2f9225f9fef4a24d /sys/powerpc/aim/copyinout.c | |
parent | 05f21bfd38be9286a027830654ed629c3d77310a (diff) | |
download | FreeBSD-src-489c1437aad80456391795b153ab87e37f44680d.zip FreeBSD-src-489c1437aad80456391795b153ab87e37f44680d.tar.gz |
Replace the SLB backing store splay tree used on 64-bit PowerPC AIM
hardware with a lockless sparse tree design. This marginally improves
the performance of PMAP and allows copyin()/copyout() to run without
acquiring locks when used on wired mappings.
Submitted by: mdf
Diffstat (limited to 'sys/powerpc/aim/copyinout.c')
-rw-r--r-- | sys/powerpc/aim/copyinout.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/powerpc/aim/copyinout.c b/sys/powerpc/aim/copyinout.c index 35d0ee4..ab2d1f32 100644 --- a/sys/powerpc/aim/copyinout.c +++ b/sys/powerpc/aim/copyinout.c @@ -80,16 +80,28 @@ int setfault(faultbuf); /* defined in locore.S */ static __inline void set_user_sr(pmap_t pm, const void *addr) { + struct slb *slb; register_t esid, vsid, slb1, slb2; esid = USER_ADDR >> ADDR_SR_SHFT; - PMAP_LOCK(pm); - vsid = va_to_vsid(pm, (vm_offset_t)addr); - PMAP_UNLOCK(pm); + + /* Try lockless look-up first */ + slb = user_va_to_slb_entry(pm, (vm_offset_t)addr); + + if (slb == NULL) { + /* If it isn't there, we need to pre-fault the VSID */ + PMAP_LOCK(pm); + vsid = va_to_vsid(pm, (vm_offset_t)addr); + PMAP_UNLOCK(pm); + } else { + vsid = slb->slbv >> SLBV_VSID_SHIFT; + } slb1 = vsid << SLBV_VSID_SHIFT; slb2 = (esid << SLBE_ESID_SHIFT) | SLBE_VALID | USER_SR; + curthread->td_pcb->pcb_cpu.aim.usr_segm = + (uintptr_t)addr >> ADDR_SR_SHFT; __asm __volatile ("slbie %0; slbmte %1, %2" :: "r"(esid << 28), "r"(slb1), "r"(slb2)); isync(); |