1 From: Petr Tesarik <ptesarik@suse.cz>
2 Subject: [ia64] re-enable interrupts when waiting for a rwlock
6 Re-enable interrupts for _read_lock_irqsave() and _write_lock_irqsave()
7 while waiting for the lock if interrupts were enabled in the caller.
9 Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
12 arch/ia64/include/asm/spinlock.h | 49 ++++++++++++++++++++++++++++++++++-----
13 1 file changed, 43 insertions(+), 6 deletions(-)
15 --- linux-2.6.26.orig/arch/ia64/include/asm/spinlock.h 2008-09-26 13:02:50.000000000 +0200
16 +++ linux-2.6.26/arch/ia64/include/asm/spinlock.h 2008-09-26 15:54:11.000000000 +0200
17 @@ -120,6 +120,35 @@ do { \
18 #define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0)
19 #define __raw_write_can_lock(rw) (*(volatile int *)(rw) == 0)
22 +#define __raw_read_lock_flags(rw, flags) \
24 + __asm__ __volatile__ ( \
25 + "tbit.nz p6,p0 = %1,%2\n" \
28 + "fetchadd4.rel r2 = [%0],-1;;\n" \
29 + "(p6) ssm psr.i\n" \
32 + "ld4 r2 = [%0];;\n" \
33 + "cmp4.lt p7,p0 = r2,r0\n" \
34 + "(p7) br.cond.spnt.few 2b\n" \
35 + "(p6) rsm psr.i;;\n" \
37 + "fetchadd4.acq r2 = [%0],1;;\n" \
38 + "cmp4.lt p7,p0 = r2,r0\n" \
39 + "(p7) br.cond.spnt.few 1b\n" \
40 + :: "r"(rw), "r"(flags), "i"(IA64_PSR_I_BIT) \
41 + : "p6", "p7", "r2", "memory"); \
44 +#define __raw_read_lock(lock) __raw_read_lock_flags(lock, 0)
46 +#else /* !ASM_SUPPORTED */
48 +#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw)
50 #define __raw_read_lock(rw) \
52 raw_rwlock_t *__read_lock_ptr = (rw); \
53 @@ -131,6 +160,8 @@ do { \
57 +#endif /* !ASM_SUPPORTED */
59 #define __raw_read_unlock(rw) \
61 raw_rwlock_t *__read_lock_ptr = (rw); \
62 @@ -138,21 +169,28 @@ do { \
66 -#define __raw_write_lock(rw) \
67 +#define __raw_write_lock_flags(rw, flags) \
69 __asm__ __volatile__ ( \
71 + "tbit.nz p6,p0 = %1,%2\n" \
72 "dep r29 = -1, r0, 31, 1;;\n" \
74 + "(p6) ssm psr.i\n" \
77 "cmp4.eq p0,p7 = r0,r2\n" \
78 - "(p7) br.cond.spnt.few 1b \n" \
79 + "(p7) br.cond.spnt.few 2b \n" \
80 + "(p6) rsm psr.i;;\n" \
81 "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" \
82 "cmp4.eq p0,p7 = r0, r2\n" \
83 "(p7) br.cond.spnt.few 1b;;\n" \
84 - :: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \
85 + :: "r"(rw), "r"(flags), "i"(IA64_PSR_I_BIT) \
86 + : "ar.ccv", "p6", "p7", "r2", "r29", "memory"); \
89 +#define __raw_write_lock(rw) __raw_write_lock_flags(rw, 0)
91 #define __raw_write_trylock(rw) \
93 register long result; \
94 @@ -174,6 +212,8 @@ static inline void __raw_write_unlock(ra
96 #else /* !ASM_SUPPORTED */
98 +#define __raw_write_lock_flags(l, flags) __raw_write_lock(l)
100 #define __raw_write_lock(l) \
102 __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
103 @@ -213,9 +253,6 @@ static inline int __raw_read_trylock(raw
104 return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word;
107 -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
108 -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
110 #define _raw_spin_relax(lock) cpu_relax()
111 #define _raw_read_relax(lock) cpu_relax()
112 #define _raw_write_relax(lock) cpu_relax()