aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/vector.S
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2012-04-15 20:56:45 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-04-30 15:37:17 +1000
commit35000870fcfbb28757ad47de77b4645072d916b8 (patch)
tree92e9fe4570f7239e514b1254090cc595827f0dff /arch/powerpc/kernel/vector.S
parentpowerpc: Remove empty giveup_altivec function on book3e CPUs (diff)
downloadlinux-dev-35000870fcfbb28757ad47de77b4645072d916b8.tar.xz
linux-dev-35000870fcfbb28757ad47de77b4645072d916b8.zip
powerpc: Optimise enable_kernel_altivec
Add two optimisations to enable_kernel_altivec: - enable_kernel_altivec has already determined if we need to save the previous task's state but we call giveup_altivec in both cases, requiring an extra branch in giveup_altivec. Create giveup_altivec_notask which only turns on the VMX bit in the MSR. - We write the VMX MSR bit each time we call enable_kernel_altivec even it was already set. Check the bit and branch out if we have already set it. The classic case for this is vectored IO where we have to copy multiple buffers to or from userspace. The following testcase was used to confirm this patch improves performance: http://ozlabs.org/~anton/junkcode/copy_to_user.c Since the current breakpoint for using VMX in copy_tofrom_user is 4096 bytes, I'm using buffers of 4096 + 1 cacheline (4224) bytes. A benchmark of 16 entry readvs (-s 16): time copy_to_user -l 4224 -s 16 -i 1000000 completes 5.2% faster on a POWER7 PS700. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/vector.S')
-rw-r--r--arch/powerpc/kernel/vector.S10
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index 4d5a3edff49e..e830289d2e48 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -89,6 +89,16 @@ _GLOBAL(load_up_altivec)
/* restore registers and return */
blr
+_GLOBAL(giveup_altivec_notask)
+ mfmsr r3
+ andis. r4,r3,MSR_VEC@h
+ bnelr /* Already enabled? */
+ oris r3,r3,MSR_VEC@h
+ SYNC
+ MTMSRD(r3) /* enable use of VMX now */
+ isync
+ blr
+
/*
* giveup_altivec(tsk)
* Disable VMX for the task given as the argument,