diff options
author | John David Anglin | 2011-10-09 16:40:10 -0400 |
---|---|---|
committer | James Bottomley | 2012-02-27 09:35:08 -0600 |
commit | 8b232816057702d5c9ffeac1a65118f504524fea (patch) | |
tree | 7cc6c65fbd2613c1216c2625ed27e2f1476a2997 /arch | |
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>
Diffstat (limited to 'arch')
-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 @@ #include <asm/atomic.h> #include <asm/errno.h> +/* The following has to match the LWS code in syscall.S. We have + sixteen four-word locks. */ + +static inline void +_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) +{ + extern u32 lws_lock_start[]; + long index = ((long)uaddr & 0xf0) >> 2; + arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; + local_irq_save(*flags); + arch_spin_lock(s); +} + +static inline void +_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) +{ + extern u32 lws_lock_start[]; + long index = ((long)uaddr & 0xf0) >> 2; + arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; + arch_spin_unlock(s); + local_irq_restore(*flags); +} + static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) { @@ -26,7 +49,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_disable(); - _atomic_spin_lock_irqsave(uaddr, flags); + _futex_spin_lock_irqsave(uaddr, &flags); switch (op) { case FUTEX_OP_SET: @@ -71,7 +94,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ret = -ENOSYS; } - _atomic_spin_unlock_irqrestore(uaddr, flags); + _futex_spin_unlock_irqrestore(uaddr, &flags); pagefault_enable(); @@ -113,7 +136,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, * address. This should scale to a couple of CPUs. */ - _atomic_spin_lock_irqsave(uaddr, flags); + _futex_spin_lock_irqsave(uaddr, &flags); ret = get_user(val, uaddr); @@ -122,7 +145,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, *uval = val; - _atomic_spin_unlock_irqrestore(uaddr, flags); + _futex_spin_unlock_irqrestore(uaddr, &flags); return ret; } |