summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/copyinout.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-09-16 00:22:25 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-09-16 00:22:25 +0000
commit489c1437aad80456391795b153ab87e37f44680d (patch)
tree5545963fb3f01498f05522fd2f9225f9fef4a24d /sys/powerpc/aim/copyinout.c
parent05f21bfd38be9286a027830654ed629c3d77310a (diff)
downloadFreeBSD-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.c18
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();
OpenPOWER on IntegriCloud