diff options
author | Jan Beulich <JBeulich@novell.com> | 2011-07-19 08:00:19 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-07-21 03:03:32 -0400 |
commit | a738669464a1e0d8e7b20f631120192f9cf7cfbd (patch) | |
tree | 1388cef07865ef0f8ddd298bfdbebbbe25efc514 /arch/x86/lib | |
parent | 4625cd637919edfb562e0d62abf94f52e9321335 (diff) |
x86: Unify rwsem assembly implementation
Rather than having two functionally identical implementations
for 32- and 64-bit configurations, use the previously extended
assembly abstractions to fold the rwsem two implementations into
a shared one.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/4E258DF3020000780004E3ED@nat28.tlf.novell.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/lib/rwsem.S (renamed from arch/x86/lib/rwsem_64.S) | 75 | ||||
-rw-r--r-- | arch/x86/lib/semaphore_32.S | 80 |
3 files changed, 60 insertions, 98 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index d3ed1203cdd7..5d46ddcb69c5 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -21,6 +21,7 @@ lib-y += thunk_$(BITS).o | |||
21 | lib-y += usercopy_$(BITS).o getuser.o putuser.o | 21 | lib-y += usercopy_$(BITS).o getuser.o putuser.o |
22 | lib-y += memcpy_$(BITS).o | 22 | lib-y += memcpy_$(BITS).o |
23 | lib-$(CONFIG_SMP) += rwlock.o | 23 | lib-$(CONFIG_SMP) += rwlock.o |
24 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | ||
24 | lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o | 25 | lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o |
25 | 26 | ||
26 | obj-y += msr.o msr-reg.o msr-reg-export.o | 27 | obj-y += msr.o msr-reg.o msr-reg-export.o |
@@ -30,7 +31,6 @@ ifeq ($(CONFIG_X86_32),y) | |||
30 | lib-y += atomic64_cx8_32.o | 31 | lib-y += atomic64_cx8_32.o |
31 | lib-y += checksum_32.o | 32 | lib-y += checksum_32.o |
32 | lib-y += strstr_32.o | 33 | lib-y += strstr_32.o |
33 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += semaphore_32.o | ||
34 | lib-y += string_32.o | 34 | lib-y += string_32.o |
35 | lib-y += cmpxchg.o | 35 | lib-y += cmpxchg.o |
36 | ifneq ($(CONFIG_X86_CMPXCHG64),y) | 36 | ifneq ($(CONFIG_X86_CMPXCHG64),y) |
@@ -43,6 +43,5 @@ else | |||
43 | lib-y += thunk_64.o clear_page_64.o copy_page_64.o | 43 | lib-y += thunk_64.o clear_page_64.o copy_page_64.o |
44 | lib-y += memmove_64.o memset_64.o | 44 | lib-y += memmove_64.o memset_64.o |
45 | lib-y += copy_user_64.o copy_user_nocache_64.o | 45 | lib-y += copy_user_64.o copy_user_nocache_64.o |
46 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o | ||
47 | lib-y += cmpxchg16b_emu.o | 46 | lib-y += cmpxchg16b_emu.o |
48 | endif | 47 | endif |
diff --git a/arch/x86/lib/rwsem_64.S b/arch/x86/lib/rwsem.S index 67743977398b..5dff5f042468 100644 --- a/arch/x86/lib/rwsem_64.S +++ b/arch/x86/lib/rwsem.S | |||
@@ -1,4 +1,51 @@ | |||
1 | /* | 1 | /* |
2 | * x86 semaphore implementation. | ||
3 | * | ||
4 | * (C) Copyright 1999 Linus Torvalds | ||
5 | * | ||
6 | * Portions Copyright 1999 Red Hat, Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | ||
14 | */ | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | #include <asm/alternative-asm.h> | ||
18 | #include <asm/dwarf2.h> | ||
19 | |||
20 | #define __ASM_HALF_REG(reg) __ASM_SEL(reg, e##reg) | ||
21 | #define __ASM_HALF_SIZE(inst) __ASM_SEL(inst##w, inst##l) | ||
22 | |||
23 | #ifdef CONFIG_X86_32 | ||
24 | |||
25 | /* | ||
26 | * The semaphore operations have a special calling sequence that | ||
27 | * allow us to do a simpler in-line version of them. These routines | ||
28 | * need to convert that sequence back into the C sequence when | ||
29 | * there is contention on the semaphore. | ||
30 | * | ||
31 | * %eax contains the semaphore pointer on entry. Save the C-clobbered | ||
32 | * registers (%eax, %edx and %ecx) except %eax whish is either a return | ||
33 | * value or just clobbered.. | ||
34 | */ | ||
35 | |||
36 | #define save_common_regs \ | ||
37 | pushl_cfi %ecx; CFI_REL_OFFSET ecx, 0 | ||
38 | |||
39 | #define restore_common_regs \ | ||
40 | popl_cfi %ecx; CFI_RESTORE ecx | ||
41 | |||
42 | /* Avoid uglifying the argument copying x86-64 needs to do. */ | ||
43 | .macro movq src, dst | ||
44 | .endm | ||
45 | |||
46 | #else | ||
47 | |||
48 | /* | ||
2 | * x86-64 rwsem wrappers | 49 | * x86-64 rwsem wrappers |
3 | * | 50 | * |
4 | * This interfaces the inline asm code to the slow-path | 51 | * This interfaces the inline asm code to the slow-path |
@@ -16,12 +63,6 @@ | |||
16 | * but %rdi, %rsi, %rcx, %r8-r11 always need saving. | 63 | * but %rdi, %rsi, %rcx, %r8-r11 always need saving. |
17 | */ | 64 | */ |
18 | 65 | ||
19 | #include <linux/linkage.h> | ||
20 | #include <asm/rwlock.h> | ||
21 | #include <asm/alternative-asm.h> | ||
22 | #include <asm/frame.h> | ||
23 | #include <asm/dwarf2.h> | ||
24 | |||
25 | #define save_common_regs \ | 66 | #define save_common_regs \ |
26 | pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \ | 67 | pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \ |
27 | pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \ | 68 | pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \ |
@@ -40,16 +81,18 @@ | |||
40 | popq_cfi %rsi; CFI_RESTORE rsi; \ | 81 | popq_cfi %rsi; CFI_RESTORE rsi; \ |
41 | popq_cfi %rdi; CFI_RESTORE rdi | 82 | popq_cfi %rdi; CFI_RESTORE rdi |
42 | 83 | ||
84 | #endif | ||
85 | |||
43 | /* Fix up special calling conventions */ | 86 | /* Fix up special calling conventions */ |
44 | ENTRY(call_rwsem_down_read_failed) | 87 | ENTRY(call_rwsem_down_read_failed) |
45 | CFI_STARTPROC | 88 | CFI_STARTPROC |
46 | save_common_regs | 89 | save_common_regs |
47 | pushq_cfi %rdx | 90 | __ASM_SIZE(push,_cfi) %__ASM_REG(dx) |
48 | CFI_REL_OFFSET rdx, 0 | 91 | CFI_REL_OFFSET __ASM_REG(dx), 0 |
49 | movq %rax,%rdi | 92 | movq %rax,%rdi |
50 | call rwsem_down_read_failed | 93 | call rwsem_down_read_failed |
51 | popq_cfi %rdx | 94 | __ASM_SIZE(pop,_cfi) %__ASM_REG(dx) |
52 | CFI_RESTORE rdx | 95 | CFI_RESTORE __ASM_REG(dx) |
53 | restore_common_regs | 96 | restore_common_regs |
54 | ret | 97 | ret |
55 | CFI_ENDPROC | 98 | CFI_ENDPROC |
@@ -67,7 +110,8 @@ ENDPROC(call_rwsem_down_write_failed) | |||
67 | 110 | ||
68 | ENTRY(call_rwsem_wake) | 111 | ENTRY(call_rwsem_wake) |
69 | CFI_STARTPROC | 112 | CFI_STARTPROC |
70 | decl %edx /* do nothing if still outstanding active readers */ | 113 | /* do nothing if still outstanding active readers */ |
114 | __ASM_HALF_SIZE(dec) %__ASM_HALF_REG(dx) | ||
71 | jnz 1f | 115 | jnz 1f |
72 | save_common_regs | 116 | save_common_regs |
73 | movq %rax,%rdi | 117 | movq %rax,%rdi |
@@ -77,16 +121,15 @@ ENTRY(call_rwsem_wake) | |||
77 | CFI_ENDPROC | 121 | CFI_ENDPROC |
78 | ENDPROC(call_rwsem_wake) | 122 | ENDPROC(call_rwsem_wake) |
79 | 123 | ||
80 | /* Fix up special calling conventions */ | ||
81 | ENTRY(call_rwsem_downgrade_wake) | 124 | ENTRY(call_rwsem_downgrade_wake) |
82 | CFI_STARTPROC | 125 | CFI_STARTPROC |
83 | save_common_regs | 126 | save_common_regs |
84 | pushq_cfi %rdx | 127 | __ASM_SIZE(push,_cfi) %__ASM_REG(dx) |
85 | CFI_REL_OFFSET rdx, 0 | 128 | CFI_REL_OFFSET __ASM_REG(dx), 0 |
86 | movq %rax,%rdi | 129 | movq %rax,%rdi |
87 | call rwsem_downgrade_wake | 130 | call rwsem_downgrade_wake |
88 | popq_cfi %rdx | 131 | __ASM_SIZE(pop,_cfi) %__ASM_REG(dx) |
89 | CFI_RESTORE rdx | 132 | CFI_RESTORE __ASM_REG(dx) |
90 | restore_common_regs | 133 | restore_common_regs |
91 | ret | 134 | ret |
92 | CFI_ENDPROC | 135 | CFI_ENDPROC |
diff --git a/arch/x86/lib/semaphore_32.S b/arch/x86/lib/semaphore_32.S deleted file mode 100644 index 65b591d778b1..000000000000 --- a/arch/x86/lib/semaphore_32.S +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* | ||
2 | * i386 semaphore implementation. | ||
3 | * | ||
4 | * (C) Copyright 1999 Linus Torvalds | ||
5 | * | ||
6 | * Portions Copyright 1999 Red Hat, Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | ||
14 | */ | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | #include <asm/frame.h> | ||
18 | #include <asm/dwarf2.h> | ||
19 | |||
20 | /* | ||
21 | * The semaphore operations have a special calling sequence that | ||
22 | * allow us to do a simpler in-line version of them. These routines | ||
23 | * need to convert that sequence back into the C sequence when | ||
24 | * there is contention on the semaphore. | ||
25 | * | ||
26 | * %eax contains the semaphore pointer on entry. Save the C-clobbered | ||
27 | * registers (%eax, %edx and %ecx) except %eax whish is either a return | ||
28 | * value or just clobbered.. | ||
29 | */ | ||
30 | .section .sched.text, "ax" | ||
31 | |||
32 | /* Fix up special calling conventions */ | ||
33 | ENTRY(call_rwsem_down_read_failed) | ||
34 | CFI_STARTPROC | ||
35 | pushl_cfi %ecx | ||
36 | CFI_REL_OFFSET ecx,0 | ||
37 | pushl_cfi %edx | ||
38 | CFI_REL_OFFSET edx,0 | ||
39 | call rwsem_down_read_failed | ||
40 | popl_cfi %edx | ||
41 | popl_cfi %ecx | ||
42 | ret | ||
43 | CFI_ENDPROC | ||
44 | ENDPROC(call_rwsem_down_read_failed) | ||
45 | |||
46 | ENTRY(call_rwsem_down_write_failed) | ||
47 | CFI_STARTPROC | ||
48 | pushl_cfi %ecx | ||
49 | CFI_REL_OFFSET ecx,0 | ||
50 | calll rwsem_down_write_failed | ||
51 | popl_cfi %ecx | ||
52 | ret | ||
53 | CFI_ENDPROC | ||
54 | ENDPROC(call_rwsem_down_write_failed) | ||
55 | |||
56 | ENTRY(call_rwsem_wake) | ||
57 | CFI_STARTPROC | ||
58 | decw %dx /* do nothing if still outstanding active readers */ | ||
59 | jnz 1f | ||
60 | pushl_cfi %ecx | ||
61 | CFI_REL_OFFSET ecx,0 | ||
62 | call rwsem_wake | ||
63 | popl_cfi %ecx | ||
64 | 1: ret | ||
65 | CFI_ENDPROC | ||
66 | ENDPROC(call_rwsem_wake) | ||
67 | |||
68 | /* Fix up special calling conventions */ | ||
69 | ENTRY(call_rwsem_downgrade_wake) | ||
70 | CFI_STARTPROC | ||
71 | pushl_cfi %ecx | ||
72 | CFI_REL_OFFSET ecx,0 | ||
73 | pushl_cfi %edx | ||
74 | CFI_REL_OFFSET edx,0 | ||
75 | call rwsem_downgrade_wake | ||
76 | popl_cfi %edx | ||
77 | popl_cfi %ecx | ||
78 | ret | ||
79 | CFI_ENDPROC | ||
80 | ENDPROC(call_rwsem_downgrade_wake) | ||