diff options
author | Oleg Nesterov <oleg@redhat.com> | 2014-09-21 14:41:53 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-09-24 09:15:38 -0400 |
commit | 0ad6e3c5199be12c9745da8f8b9e3c9f8066c235 (patch) | |
tree | 581d938c3bf976c54a95b2fd6030c232b7885031 /arch/x86/lib | |
parent | f3670394c29ff3730638762c1760fd2f624e6d7b (diff) |
x86: Speed up ___preempt_schedule*() by using THUNK helpers
___preempt_schedule() does SAVE_ALL/RESTORE_ALL but this is
suboptimal, we do not need to save/restore the callee-saved
register. And we already have arch/x86/lib/thunk_*.S which
implements the similar asm wrappers, so it makes sense to
redefine ___preempt_schedule() as "THUNK ..." and remove
preempt.S altogether.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/20140921184153.GA23727@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/thunk_32.S | 20 | ||||
-rw-r--r-- | arch/x86/lib/thunk_64.S | 7 |
2 files changed, 23 insertions, 4 deletions
diff --git a/arch/x86/lib/thunk_32.S b/arch/x86/lib/thunk_32.S index 28f85c916712..e9acf5f4fc92 100644 --- a/arch/x86/lib/thunk_32.S +++ b/arch/x86/lib/thunk_32.S | |||
@@ -7,16 +7,19 @@ | |||
7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
8 | #include <asm/asm.h> | 8 | #include <asm/asm.h> |
9 | 9 | ||
10 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
11 | /* put return address in eax (arg1) */ | 10 | /* put return address in eax (arg1) */ |
12 | .macro thunk_ra name,func | 11 | .macro THUNK name, func, put_ret_addr_in_eax=0 |
13 | .globl \name | 12 | .globl \name |
14 | \name: | 13 | \name: |
15 | pushl %eax | 14 | pushl %eax |
16 | pushl %ecx | 15 | pushl %ecx |
17 | pushl %edx | 16 | pushl %edx |
17 | |||
18 | .if \put_ret_addr_in_eax | ||
18 | /* Place EIP in the arg1 */ | 19 | /* Place EIP in the arg1 */ |
19 | movl 3*4(%esp), %eax | 20 | movl 3*4(%esp), %eax |
21 | .endif | ||
22 | |||
20 | call \func | 23 | call \func |
21 | popl %edx | 24 | popl %edx |
22 | popl %ecx | 25 | popl %ecx |
@@ -25,6 +28,15 @@ | |||
25 | _ASM_NOKPROBE(\name) | 28 | _ASM_NOKPROBE(\name) |
26 | .endm | 29 | .endm |
27 | 30 | ||
28 | thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller | 31 | #ifdef CONFIG_TRACE_IRQFLAGS |
29 | thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller | 32 | THUNK trace_hardirqs_on_thunk,trace_hardirqs_on_caller,1 |
33 | THUNK trace_hardirqs_off_thunk,trace_hardirqs_off_caller,1 | ||
34 | #endif | ||
35 | |||
36 | #ifdef CONFIG_PREEMPT | ||
37 | THUNK ___preempt_schedule, preempt_schedule | ||
38 | #ifdef CONFIG_CONTEXT_TRACKING | ||
39 | THUNK ___preempt_schedule_context, preempt_schedule_context | ||
30 | #endif | 40 | #endif |
41 | #endif | ||
42 | |||
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index 92d9feaff42b..b30b5ebd614a 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S | |||
@@ -38,6 +38,13 @@ | |||
38 | THUNK lockdep_sys_exit_thunk,lockdep_sys_exit | 38 | THUNK lockdep_sys_exit_thunk,lockdep_sys_exit |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #ifdef CONFIG_PREEMPT | ||
42 | THUNK ___preempt_schedule, preempt_schedule | ||
43 | #ifdef CONFIG_CONTEXT_TRACKING | ||
44 | THUNK ___preempt_schedule_context, preempt_schedule_context | ||
45 | #endif | ||
46 | #endif | ||
47 | |||
41 | /* SAVE_ARGS below is used only for the .cfi directives it contains. */ | 48 | /* SAVE_ARGS below is used only for the .cfi directives it contains. */ |
42 | CFI_STARTPROC | 49 | CFI_STARTPROC |
43 | SAVE_ARGS | 50 | SAVE_ARGS |