diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-03-02 07:09:47 -0500 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-17 22:54:30 -0400 |
commit | 1423523b9a857e3b227e12d484c996f1846aa29e (patch) | |
tree | b891d0546acbb9993aa70b4d5ef22a7753f2a5e2 /kernel | |
parent | 4ded95ddc4a08a5b90f42307a51624268a0e710e (diff) |
futex: Allow architectures to skip futex_atomic_cmpxchg_inatomic() test
If an architecture has futex_atomic_cmpxchg_inatomic() implemented and there
is no runtime check necessary, allow to skip the test within futex_init().
This allows to get rid of some code which would always give the same result,
and also allows the compiler to optimize a couple of if statements away.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Finn Thain <fthain@telegraphics.com.au>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Link: http://lkml.kernel.org/r/20140302120947.GA3641@osiris
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/futex.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index bdc420d30a03..a3502ad21cbb 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -157,7 +157,9 @@ | |||
157 | * enqueue. | 157 | * enqueue. |
158 | */ | 158 | */ |
159 | 159 | ||
160 | #ifndef CONFIG_HAVE_FUTEX_CMPXCHG | ||
160 | int __read_mostly futex_cmpxchg_enabled; | 161 | int __read_mostly futex_cmpxchg_enabled; |
162 | #endif | ||
161 | 163 | ||
162 | /* | 164 | /* |
163 | * Futex flags used to encode options to functions and preserve them across | 165 | * Futex flags used to encode options to functions and preserve them across |
@@ -2841,9 +2843,28 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, | |||
2841 | return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); | 2843 | return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); |
2842 | } | 2844 | } |
2843 | 2845 | ||
2844 | static int __init futex_init(void) | 2846 | static void __init futex_detect_cmpxchg(void) |
2845 | { | 2847 | { |
2848 | #ifndef CONFIG_HAVE_FUTEX_CMPXCHG | ||
2846 | u32 curval; | 2849 | u32 curval; |
2850 | |||
2851 | /* | ||
2852 | * This will fail and we want it. Some arch implementations do | ||
2853 | * runtime detection of the futex_atomic_cmpxchg_inatomic() | ||
2854 | * functionality. We want to know that before we call in any | ||
2855 | * of the complex code paths. Also we want to prevent | ||
2856 | * registration of robust lists in that case. NULL is | ||
2857 | * guaranteed to fault and we get -EFAULT on functional | ||
2858 | * implementation, the non-functional ones will return | ||
2859 | * -ENOSYS. | ||
2860 | */ | ||
2861 | if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT) | ||
2862 | futex_cmpxchg_enabled = 1; | ||
2863 | #endif | ||
2864 | } | ||
2865 | |||
2866 | static int __init futex_init(void) | ||
2867 | { | ||
2847 | unsigned int futex_shift; | 2868 | unsigned int futex_shift; |
2848 | unsigned long i; | 2869 | unsigned long i; |
2849 | 2870 | ||
@@ -2859,18 +2880,8 @@ static int __init futex_init(void) | |||
2859 | &futex_shift, NULL, | 2880 | &futex_shift, NULL, |
2860 | futex_hashsize, futex_hashsize); | 2881 | futex_hashsize, futex_hashsize); |
2861 | futex_hashsize = 1UL << futex_shift; | 2882 | futex_hashsize = 1UL << futex_shift; |
2862 | /* | 2883 | |
2863 | * This will fail and we want it. Some arch implementations do | 2884 | futex_detect_cmpxchg(); |
2864 | * runtime detection of the futex_atomic_cmpxchg_inatomic() | ||
2865 | * functionality. We want to know that before we call in any | ||
2866 | * of the complex code paths. Also we want to prevent | ||
2867 | * registration of robust lists in that case. NULL is | ||
2868 | * guaranteed to fault and we get -EFAULT on functional | ||
2869 | * implementation, the non-functional ones will return | ||
2870 | * -ENOSYS. | ||
2871 | */ | ||
2872 | if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT) | ||
2873 | futex_cmpxchg_enabled = 1; | ||
2874 | 2885 | ||
2875 | for (i = 0; i < futex_hashsize; i++) { | 2886 | for (i = 0; i < futex_hashsize; i++) { |
2876 | plist_head_init(&futex_queues[i].chain); | 2887 | plist_head_init(&futex_queues[i].chain); |