diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2015-08-06 15:41:06 +0200 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-08-20 14:46:01 +0200 |
commit | eb2cd8b72b08fe56998600aee8a5dff93f7be5a2 (patch) | |
tree | f16645c5a57ce9221e2c6ced11b73789ea9d242c /arch/arc | |
parent | ARC: Enable HAVE_FUTEX_CMPXCHG (diff) | |
download | linux-eb2cd8b72b08fe56998600aee8a5dff93f7be5a2.tar.xz linux-eb2cd8b72b08fe56998600aee8a5dff93f7be5a2.zip |
ARC: ensure futex ops are atomic in !LLSC config
W/o hardware assisted atomic r-m-w the best we can do is to disable
preemption.
Cc: David Hildenbrand <dahi@linux.vnet.ibm.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Michel Lespinasse <walken@google.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/include/asm/futex.h | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/arc/include/asm/futex.h b/arch/arc/include/asm/futex.h index 0ea8bcc7b846..8f449982523b 100644 --- a/arch/arc/include/asm/futex.h +++ b/arch/arc/include/asm/futex.h @@ -87,6 +87,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; +#ifndef CONFIG_ARC_HAS_LLSC + preempt_disable(); /* to guarantee atomic r-m-w of futex op */ +#endif pagefault_disable(); switch (op) { @@ -111,6 +114,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); +#ifndef CONFIG_ARC_HAS_LLSC + preempt_enable(); +#endif if (!ret) { switch (cmp) { @@ -153,6 +159,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 expval, if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; +#ifndef CONFIG_ARC_HAS_LLSC + preempt_disable(); /* to guarantee atomic r-m-w of futex op */ +#endif smp_mb(); __asm__ __volatile__( @@ -182,6 +191,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 expval, smp_mb(); +#ifndef CONFIG_ARC_HAS_LLSC + preempt_enable(); +#endif *uval = existval; return ret; } |