aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@novell.com>2011-07-19 07:59:51 -0400
committerIngo Molnar <mingo@elte.hu>2011-07-21 03:03:31 -0400
commit4625cd637919edfb562e0d62abf94f52e9321335 (patch)
tree88c4cf965722fb54731a6e8f632ec6ef6e83e194
parentdd2897bf0f4d523238e87dabb23e9634ea9ba73d (diff)
x86: Unify rwlock assembly implementation
Rather than having two functionally identical implementations for 32- and 64-bit configurations, extend the existing assembly abstractions enough to fold the two rwlock 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/4E258DD7020000780004E3EA@nat28.tlf.novell.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/include/asm/asm.h3
-rw-r--r--arch/x86/include/asm/frame.h11
-rw-r--r--arch/x86/lib/Makefile6
-rw-r--r--arch/x86/lib/rwlock.S44
-rw-r--r--arch/x86/lib/rwlock_64.S38
-rw-r--r--arch/x86/lib/semaphore_32.S44
6 files changed, 56 insertions, 90 deletions
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index b3ed1e1460ff..5890beb021c4 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -15,7 +15,8 @@
15# define __ASM_SEL(a,b) __ASM_FORM(b) 15# define __ASM_SEL(a,b) __ASM_FORM(b)
16#endif 16#endif
17 17
18#define __ASM_SIZE(inst) __ASM_SEL(inst##l, inst##q) 18#define __ASM_SIZE(inst, ...) __ASM_SEL(inst##l##__VA_ARGS__, \
19 inst##q##__VA_ARGS__)
19#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg) 20#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg)
20 21
21#define _ASM_PTR __ASM_SEL(.long, .quad) 22#define _ASM_PTR __ASM_SEL(.long, .quad)
diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h
index 2c6fc9e62812..3b629f47eb65 100644
--- a/arch/x86/include/asm/frame.h
+++ b/arch/x86/include/asm/frame.h
@@ -1,5 +1,6 @@
1#ifdef __ASSEMBLY__ 1#ifdef __ASSEMBLY__
2 2
3#include <asm/asm.h>
3#include <asm/dwarf2.h> 4#include <asm/dwarf2.h>
4 5
5/* The annotation hides the frame from the unwinder and makes it look 6/* The annotation hides the frame from the unwinder and makes it look
@@ -7,13 +8,13 @@
7 frame pointer later */ 8 frame pointer later */
8#ifdef CONFIG_FRAME_POINTER 9#ifdef CONFIG_FRAME_POINTER
9 .macro FRAME 10 .macro FRAME
10 pushl_cfi %ebp 11 __ASM_SIZE(push,_cfi) %__ASM_REG(bp)
11 CFI_REL_OFFSET ebp,0 12 CFI_REL_OFFSET __ASM_REG(bp), 0
12 movl %esp,%ebp 13 __ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp)
13 .endm 14 .endm
14 .macro ENDFRAME 15 .macro ENDFRAME
15 popl_cfi %ebp 16 __ASM_SIZE(pop,_cfi) %__ASM_REG(bp)
16 CFI_RESTORE ebp 17 CFI_RESTORE __ASM_REG(bp)
17 .endm 18 .endm
18#else 19#else
19 .macro FRAME 20 .macro FRAME
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index f2479f19ddde..d3ed1203cdd7 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -20,6 +20,7 @@ lib-y := delay.o
20lib-y += thunk_$(BITS).o 20lib-y += thunk_$(BITS).o
21lib-y += usercopy_$(BITS).o getuser.o putuser.o 21lib-y += usercopy_$(BITS).o getuser.o putuser.o
22lib-y += memcpy_$(BITS).o 22lib-y += memcpy_$(BITS).o
23lib-$(CONFIG_SMP) += rwlock.o
23lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o 24lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
24 25
25obj-y += msr.o msr-reg.o msr-reg-export.o 26obj-y += msr.o msr-reg.o msr-reg-export.o
@@ -29,7 +30,8 @@ ifeq ($(CONFIG_X86_32),y)
29 lib-y += atomic64_cx8_32.o 30 lib-y += atomic64_cx8_32.o
30 lib-y += checksum_32.o 31 lib-y += checksum_32.o
31 lib-y += strstr_32.o 32 lib-y += strstr_32.o
32 lib-y += semaphore_32.o string_32.o 33 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += semaphore_32.o
34 lib-y += string_32.o
33 lib-y += cmpxchg.o 35 lib-y += cmpxchg.o
34ifneq ($(CONFIG_X86_CMPXCHG64),y) 36ifneq ($(CONFIG_X86_CMPXCHG64),y)
35 lib-y += cmpxchg8b_emu.o atomic64_386_32.o 37 lib-y += cmpxchg8b_emu.o atomic64_386_32.o
@@ -40,7 +42,7 @@ else
40 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o 42 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
41 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
42 lib-y += memmove_64.o memset_64.o 44 lib-y += memmove_64.o memset_64.o
43 lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o 45 lib-y += copy_user_64.o copy_user_nocache_64.o
44 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o 46 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o
45 lib-y += cmpxchg16b_emu.o 47 lib-y += cmpxchg16b_emu.o
46endif 48endif
diff --git a/arch/x86/lib/rwlock.S b/arch/x86/lib/rwlock.S
new file mode 100644
index 000000000000..fca17829caa8
--- /dev/null
+++ b/arch/x86/lib/rwlock.S
@@ -0,0 +1,44 @@
1/* Slow paths of read/write spinlocks. */
2
3#include <linux/linkage.h>
4#include <asm/alternative-asm.h>
5#include <asm/frame.h>
6#include <asm/rwlock.h>
7
8#ifdef CONFIG_X86_32
9# define __lock_ptr eax
10#else
11# define __lock_ptr rdi
12#endif
13
14ENTRY(__write_lock_failed)
15 CFI_STARTPROC
16 FRAME
170: LOCK_PREFIX
18 addl $RW_LOCK_BIAS, (%__lock_ptr)
191: rep; nop
20 cmpl $RW_LOCK_BIAS, (%__lock_ptr)
21 jne 1b
22 LOCK_PREFIX
23 subl $RW_LOCK_BIAS, (%__lock_ptr)
24 jnz 0b
25 ENDFRAME
26 ret
27 CFI_ENDPROC
28END(__write_lock_failed)
29
30ENTRY(__read_lock_failed)
31 CFI_STARTPROC
32 FRAME
330: LOCK_PREFIX
34 incl (%__lock_ptr)
351: rep; nop
36 cmpl $1, (%__lock_ptr)
37 js 1b
38 LOCK_PREFIX
39 decl (%__lock_ptr)
40 js 0b
41 ENDFRAME
42 ret
43 CFI_ENDPROC
44END(__read_lock_failed)
diff --git a/arch/x86/lib/rwlock_64.S b/arch/x86/lib/rwlock_64.S
deleted file mode 100644
index 05ea55f71405..000000000000
--- a/arch/x86/lib/rwlock_64.S
+++ /dev/null
@@ -1,38 +0,0 @@
1/* Slow paths of read/write spinlocks. */
2
3#include <linux/linkage.h>
4#include <asm/rwlock.h>
5#include <asm/alternative-asm.h>
6#include <asm/dwarf2.h>
7
8/* rdi: pointer to rwlock_t */
9ENTRY(__write_lock_failed)
10 CFI_STARTPROC
11 LOCK_PREFIX
12 addl $RW_LOCK_BIAS,(%rdi)
131: rep
14 nop
15 cmpl $RW_LOCK_BIAS,(%rdi)
16 jne 1b
17 LOCK_PREFIX
18 subl $RW_LOCK_BIAS,(%rdi)
19 jnz __write_lock_failed
20 ret
21 CFI_ENDPROC
22END(__write_lock_failed)
23
24/* rdi: pointer to rwlock_t */
25ENTRY(__read_lock_failed)
26 CFI_STARTPROC
27 LOCK_PREFIX
28 incl (%rdi)
291: rep
30 nop
31 cmpl $1,(%rdi)
32 js 1b
33 LOCK_PREFIX
34 decl (%rdi)
35 js __read_lock_failed
36 ret
37 CFI_ENDPROC
38END(__read_lock_failed)
diff --git a/arch/x86/lib/semaphore_32.S b/arch/x86/lib/semaphore_32.S
index 06691daa4108..65b591d778b1 100644
--- a/arch/x86/lib/semaphore_32.S
+++ b/arch/x86/lib/semaphore_32.S
@@ -14,8 +14,6 @@
14 */ 14 */
15 15
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17#include <asm/rwlock.h>
18#include <asm/alternative-asm.h>
19#include <asm/frame.h> 17#include <asm/frame.h>
20#include <asm/dwarf2.h> 18#include <asm/dwarf2.h>
21 19
@@ -31,46 +29,6 @@
31 */ 29 */
32 .section .sched.text, "ax" 30 .section .sched.text, "ax"
33 31
34/*
35 * rw spinlock fallbacks
36 */
37#ifdef CONFIG_SMP
38ENTRY(__write_lock_failed)
39 CFI_STARTPROC
40 FRAME
412: LOCK_PREFIX
42 addl $ RW_LOCK_BIAS,(%eax)
431: rep; nop
44 cmpl $ RW_LOCK_BIAS,(%eax)
45 jne 1b
46 LOCK_PREFIX
47 subl $ RW_LOCK_BIAS,(%eax)
48 jnz 2b
49 ENDFRAME
50 ret
51 CFI_ENDPROC
52 ENDPROC(__write_lock_failed)
53
54ENTRY(__read_lock_failed)
55 CFI_STARTPROC
56 FRAME
572: LOCK_PREFIX
58 incl (%eax)
591: rep; nop
60 cmpl $1,(%eax)
61 js 1b
62 LOCK_PREFIX
63 decl (%eax)
64 js 2b
65 ENDFRAME
66 ret
67 CFI_ENDPROC
68 ENDPROC(__read_lock_failed)
69
70#endif
71
72#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
73
74/* Fix up special calling conventions */ 32/* Fix up special calling conventions */
75ENTRY(call_rwsem_down_read_failed) 33ENTRY(call_rwsem_down_read_failed)
76 CFI_STARTPROC 34 CFI_STARTPROC
@@ -120,5 +78,3 @@ ENTRY(call_rwsem_downgrade_wake)
120 ret 78 ret
121 CFI_ENDPROC 79 CFI_ENDPROC
122 ENDPROC(call_rwsem_downgrade_wake) 80 ENDPROC(call_rwsem_downgrade_wake)
123
124#endif