diff options
| author | John David Anglin <dave@hiauly1.hia.nrc.ca> | 2011-10-09 16:40:10 -0400 |
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-27 10:35:08 -0500 |
| commit | 8b232816057702d5c9ffeac1a65118f504524fea (patch) | |
| tree | 7cc6c65fbd2613c1216c2625ed27e2f1476a2997 | |
| parent | 500dd2370e77c9551ba298bdeeb91b02d8402199 (diff) | |
[PARISC] futex: Use same lock set as lws calls
In debugging the failure of the glibc tst-cond18 test on parisc, I realized
that futexes need to use the same locks the lws calls. This fixes all the
pthread 'cond' tests. Sadly, there are still problems with thread cancellation.
[jejb: checkpatch fixes]
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
| -rw-r--r-- | arch/parisc/include/asm/futex.h | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 2388bdb32832..49df14805a9b 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h | |||
| @@ -8,6 +8,29 @@ | |||
| 8 | #include <asm/atomic.h> | 8 | #include <asm/atomic.h> |
| 9 | #include <asm/errno.h> | 9 | #include <asm/errno.h> |
| 10 | 10 | ||
| 11 | /* The following has to match the LWS code in syscall.S. We have | ||
| 12 | sixteen four-word locks. */ | ||
| 13 | |||
| 14 | static inline void | ||
| 15 | _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) | ||
| 16 | { | ||
| 17 | extern u32 lws_lock_start[]; | ||
| 18 | long index = ((long)uaddr & 0xf0) >> 2; | ||
| 19 | arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; | ||
| 20 | local_irq_save(*flags); | ||
| 21 | arch_spin_lock(s); | ||
| 22 | } | ||
| 23 | |||
| 24 | static inline void | ||
| 25 | _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) | ||
| 26 | { | ||
| 27 | extern u32 lws_lock_start[]; | ||
| 28 | long index = ((long)uaddr & 0xf0) >> 2; | ||
| 29 | arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; | ||
| 30 | arch_spin_unlock(s); | ||
| 31 | local_irq_restore(*flags); | ||
| 32 | } | ||
| 33 | |||
| 11 | static inline int | 34 | static inline int |
| 12 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | 35 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
| 13 | { | 36 | { |
| @@ -26,7 +49,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | |||
| 26 | 49 | ||
| 27 | pagefault_disable(); | 50 | pagefault_disable(); |
| 28 | 51 | ||
| 29 | _atomic_spin_lock_irqsave(uaddr, flags); | 52 | _futex_spin_lock_irqsave(uaddr, &flags); |
| 30 | 53 | ||
| 31 | switch (op) { | 54 | switch (op) { |
| 32 | case FUTEX_OP_SET: | 55 | case FUTEX_OP_SET: |
| @@ -71,7 +94,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | |||
| 71 | ret = -ENOSYS; | 94 | ret = -ENOSYS; |
| 72 | } | 95 | } |
| 73 | 96 | ||
| 74 | _atomic_spin_unlock_irqrestore(uaddr, flags); | 97 | _futex_spin_unlock_irqrestore(uaddr, &flags); |
| 75 | 98 | ||
| 76 | pagefault_enable(); | 99 | pagefault_enable(); |
| 77 | 100 | ||
| @@ -113,7 +136,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 113 | * address. This should scale to a couple of CPUs. | 136 | * address. This should scale to a couple of CPUs. |
| 114 | */ | 137 | */ |
| 115 | 138 | ||
| 116 | _atomic_spin_lock_irqsave(uaddr, flags); | 139 | _futex_spin_lock_irqsave(uaddr, &flags); |
| 117 | 140 | ||
| 118 | ret = get_user(val, uaddr); | 141 | ret = get_user(val, uaddr); |
| 119 | 142 | ||
| @@ -122,7 +145,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 122 | 145 | ||
| 123 | *uval = val; | 146 | *uval = val; |
| 124 | 147 | ||
| 125 | _atomic_spin_unlock_irqrestore(uaddr, flags); | 148 | _futex_spin_unlock_irqrestore(uaddr, &flags); |
| 126 | 149 | ||
| 127 | return ret; | 150 | return ret; |
| 128 | } | 151 | } |
