Commit de4376c2 authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt

powerpc: Preload application text segment instead of TASK_UNMAPPED_BASE

TASK_UNMAPPED_BASE is not used with the new top down mmap layout. We can
reuse this preload slot by loading in the segment at 0x10000000, where almost
all PowerPC binaries are linked at.

On a microbenchmark that bounces a token between two 64bit processes over pipes
and calls gettimeofday each iteration (to access the VDSO), both the 32bit and
64bit context switch rate improves (tested on a 4GHz POWER6):

32bit: 273k/sec -> 283k/sec
64bit: 277k/sec -> 284k/sec
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 5eb9bac0
...@@ -184,7 +184,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) ...@@ -184,7 +184,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
unsigned long slbie_data = 0; unsigned long slbie_data = 0;
unsigned long pc = KSTK_EIP(tsk); unsigned long pc = KSTK_EIP(tsk);
unsigned long stack = KSTK_ESP(tsk); unsigned long stack = KSTK_ESP(tsk);
unsigned long unmapped_base; unsigned long exec_base;
if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) && if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
offset <= SLB_CACHE_ENTRIES) { offset <= SLB_CACHE_ENTRIES) {
...@@ -212,14 +212,13 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) ...@@ -212,14 +212,13 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
/* /*
* preload some userspace segments into the SLB. * preload some userspace segments into the SLB.
* Almost all 32 and 64bit PowerPC executables are linked at
* 0x10000000 so it makes sense to preload this segment.
*/ */
if (test_tsk_thread_flag(tsk, TIF_32BIT)) exec_base = 0x10000000;
unmapped_base = TASK_UNMAPPED_BASE_USER32;
else
unmapped_base = TASK_UNMAPPED_BASE_USER64;
if (is_kernel_addr(pc) || is_kernel_addr(stack) || if (is_kernel_addr(pc) || is_kernel_addr(stack) ||
is_kernel_addr(unmapped_base)) is_kernel_addr(exec_base))
return; return;
slb_allocate(pc); slb_allocate(pc);
...@@ -227,9 +226,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) ...@@ -227,9 +226,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
if (!esids_match(pc, stack)) if (!esids_match(pc, stack))
slb_allocate(stack); slb_allocate(stack);
if (!esids_match(pc, unmapped_base) && if (!esids_match(pc, exec_base) &&
!esids_match(stack, unmapped_base)) !esids_match(stack, exec_base))
slb_allocate(unmapped_base); slb_allocate(exec_base);
} }
static inline void patch_slb_encoding(unsigned int *insn_addr, static inline void patch_slb_encoding(unsigned int *insn_addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment