diff options
author | Anton Blanchard <anton@samba.org> | 2006-01-12 23:37:17 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-13 05:18:50 -0500 |
commit | 144b9c135b963bcb7f242c7b83bff930620d3161 (patch) | |
tree | 4b454f3e5e5921c5a528131dfa51df542259d918 /include/asm-powerpc/synch.h | |
parent | 3356bb9f7ba378a6e2709f9df95f4ea52111f4df (diff) |
[PATCH] powerpc: use lwsync in atomics, bitops, lock functions
eieio is only a store - store ordering. When used to order an unlock
operation loads may leak out of the critical region. This is potentially
buggy, one example is if a user wants to atomically read a couple of
values.
We can solve this with an lwsync which orders everything except store - load.
I removed the (now unused) EIEIO_ON_SMP macros and the c versions
isync_on_smp and eieio_on_smp now we dont use them. I also removed some
old comments that were used to identify inline spinlocks in assembly,
they dont make sense now our locks are out of line.
Another interesting thing was that read_unlock was using an eieio even
though the rest of the spinlock code had already been converted to
use lwsync.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc/synch.h')
-rw-r--r-- | include/asm-powerpc/synch.h | 23 |
1 files changed, 4 insertions, 19 deletions
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h index 794870ab8fd3..c90d9d9aae72 100644 --- a/include/asm-powerpc/synch.h +++ b/include/asm-powerpc/synch.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define _ASM_POWERPC_SYNCH_H | 2 | #define _ASM_POWERPC_SYNCH_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | #include <linux/stringify.h> | ||
6 | |||
5 | #ifdef __powerpc64__ | 7 | #ifdef __powerpc64__ |
6 | #define __SUBARCH_HAS_LWSYNC | 8 | #define __SUBARCH_HAS_LWSYNC |
7 | #endif | 9 | #endif |
@@ -12,20 +14,12 @@ | |||
12 | # define LWSYNC sync | 14 | # define LWSYNC sync |
13 | #endif | 15 | #endif |
14 | 16 | ||
15 | |||
16 | /* | ||
17 | * Arguably the bitops and *xchg operations don't imply any memory barrier | ||
18 | * or SMP ordering, but in fact a lot of drivers expect them to imply | ||
19 | * both, since they do on x86 cpus. | ||
20 | */ | ||
21 | #ifdef CONFIG_SMP | 17 | #ifdef CONFIG_SMP |
22 | #define EIEIO_ON_SMP "eieio\n" | ||
23 | #define ISYNC_ON_SMP "\n\tisync" | 18 | #define ISYNC_ON_SMP "\n\tisync" |
24 | #define SYNC_ON_SMP __stringify(LWSYNC) "\n" | 19 | #define LWSYNC_ON_SMP __stringify(LWSYNC) "\n" |
25 | #else | 20 | #else |
26 | #define EIEIO_ON_SMP | ||
27 | #define ISYNC_ON_SMP | 21 | #define ISYNC_ON_SMP |
28 | #define SYNC_ON_SMP | 22 | #define LWSYNC_ON_SMP |
29 | #endif | 23 | #endif |
30 | 24 | ||
31 | static inline void eieio(void) | 25 | static inline void eieio(void) |
@@ -38,14 +32,5 @@ static inline void isync(void) | |||
38 | __asm__ __volatile__ ("isync" : : : "memory"); | 32 | __asm__ __volatile__ ("isync" : : : "memory"); |
39 | } | 33 | } |
40 | 34 | ||
41 | #ifdef CONFIG_SMP | ||
42 | #define eieio_on_smp() eieio() | ||
43 | #define isync_on_smp() isync() | ||
44 | #else | ||
45 | #define eieio_on_smp() __asm__ __volatile__("": : :"memory") | ||
46 | #define isync_on_smp() __asm__ __volatile__("": : :"memory") | ||
47 | #endif | ||
48 | |||
49 | #endif /* __KERNEL__ */ | 35 | #endif /* __KERNEL__ */ |
50 | #endif /* _ASM_POWERPC_SYNCH_H */ | 36 | #endif /* _ASM_POWERPC_SYNCH_H */ |
51 | |||