aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-02 07:09:47 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-17 22:54:30 -0400
commit1423523b9a857e3b227e12d484c996f1846aa29e (patch)
treeb891d0546acbb9993aa70b4d5ef22a7753f2a5e2
parent4ded95ddc4a08a5b90f42307a51624268a0e710e (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>
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--include/linux/futex.h4
-rw-r--r--init/Kconfig7
-rw-r--r--kernel/futex.c37
4 files changed, 36 insertions, 13 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 97dcbea97a1c..d8d6eeca56b0 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -116,6 +116,7 @@ config S390
116 select HAVE_FUNCTION_GRAPH_TRACER 116 select HAVE_FUNCTION_GRAPH_TRACER
117 select HAVE_FUNCTION_TRACER 117 select HAVE_FUNCTION_TRACER
118 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 118 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
119 select HAVE_FUTEX_CMPXCHG if FUTEX
119 select HAVE_KERNEL_BZIP2 120 select HAVE_KERNEL_BZIP2
120 select HAVE_KERNEL_GZIP 121 select HAVE_KERNEL_GZIP
121 select HAVE_KERNEL_LZMA 122 select HAVE_KERNEL_LZMA
diff --git a/include/linux/futex.h b/include/linux/futex.h
index b0d95cac826e..6435f46d6e13 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -55,7 +55,11 @@ union futex_key {
55#ifdef CONFIG_FUTEX 55#ifdef CONFIG_FUTEX
56extern void exit_robust_list(struct task_struct *curr); 56extern void exit_robust_list(struct task_struct *curr);
57extern void exit_pi_state_list(struct task_struct *curr); 57extern void exit_pi_state_list(struct task_struct *curr);
58#ifdef CONFIG_HAVE_FUTEX_CMPXCHG
59#define futex_cmpxchg_enabled 1
60#else
58extern int futex_cmpxchg_enabled; 61extern int futex_cmpxchg_enabled;
62#endif
59#else 63#else
60static inline void exit_robust_list(struct task_struct *curr) 64static inline void exit_robust_list(struct task_struct *curr)
61{ 65{
diff --git a/init/Kconfig b/init/Kconfig
index 2d9b83104dcf..5d6febaea56d 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1365,6 +1365,13 @@ config FUTEX
1365 support for "fast userspace mutexes". The resulting kernel may not 1365 support for "fast userspace mutexes". The resulting kernel may not
1366 run glibc-based applications correctly. 1366 run glibc-based applications correctly.
1367 1367
1368config HAVE_FUTEX_CMPXCHG
1369 bool
1370 help
1371 Architectures should select this if futex_atomic_cmpxchg_inatomic()
1372 is implemented and always working. This removes a couple of runtime
1373 checks.
1374
1368config EPOLL 1375config EPOLL
1369 bool "Enable eventpoll support" if EXPERT 1376 bool "Enable eventpoll support" if EXPERT
1370 default y 1377 default y
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
160int __read_mostly futex_cmpxchg_enabled; 161int __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
2844static int __init futex_init(void) 2846static 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
2866static 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);