aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-02 07:09:47 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-03-03 05:32:08 -0500
commit03b8c7b623c80af264c4c8d6111e5c6289933666 (patch)
tree7fa99fe8a333d567987e563dfa4ff1cf6ee03f04
parentd2ae2e525ec4e5d58153fb7ff0c6e5873769fa73 (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 65a07750f4f9..bb74b21f007a 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -117,6 +117,7 @@ config S390
117 select HAVE_FUNCTION_GRAPH_TRACER 117 select HAVE_FUNCTION_GRAPH_TRACER
118 select HAVE_FUNCTION_TRACER 118 select HAVE_FUNCTION_TRACER
119 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 119 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
120 select HAVE_FUTEX_CMPXCHG if FUTEX
120 select HAVE_KERNEL_BZIP2 121 select HAVE_KERNEL_BZIP2
121 select HAVE_KERNEL_GZIP 122 select HAVE_KERNEL_GZIP
122 select HAVE_KERNEL_LZ4 123 select HAVE_KERNEL_LZ4
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 009a797dd242..d56cb03c1b49 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1387,6 +1387,13 @@ config FUTEX
1387 support for "fast userspace mutexes". The resulting kernel may not 1387 support for "fast userspace mutexes". The resulting kernel may not
1388 run glibc-based applications correctly. 1388 run glibc-based applications correctly.
1389 1389
1390config HAVE_FUTEX_CMPXCHG
1391 bool
1392 help
1393 Architectures should select this if futex_atomic_cmpxchg_inatomic()
1394 is implemented and always working. This removes a couple of runtime
1395 checks.
1396
1390config EPOLL 1397config EPOLL
1391 bool "Enable eventpoll support" if EXPERT 1398 bool "Enable eventpoll support" if EXPERT
1392 default y 1399 default y
diff --git a/kernel/futex.c b/kernel/futex.c
index 44a1261cb9ff..5d17e3a83f8c 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
@@ -2843,9 +2845,28 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
2843 return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); 2845 return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
2844} 2846}
2845 2847
2846static int __init futex_init(void) 2848static void __init futex_detect_cmpxchg(void)
2847{ 2849{
2850#ifndef CONFIG_HAVE_FUTEX_CMPXCHG
2848 u32 curval; 2851 u32 curval;
2852
2853 /*
2854 * This will fail and we want it. Some arch implementations do
2855 * runtime detection of the futex_atomic_cmpxchg_inatomic()
2856 * functionality. We want to know that before we call in any
2857 * of the complex code paths. Also we want to prevent
2858 * registration of robust lists in that case. NULL is
2859 * guaranteed to fault and we get -EFAULT on functional
2860 * implementation, the non-functional ones will return
2861 * -ENOSYS.
2862 */
2863 if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT)
2864 futex_cmpxchg_enabled = 1;
2865#endif
2866}
2867
2868static int __init futex_init(void)
2869{
2849 unsigned int futex_shift; 2870 unsigned int futex_shift;
2850 unsigned long i; 2871 unsigned long i;
2851 2872
@@ -2861,18 +2882,8 @@ static int __init futex_init(void)
2861 &futex_shift, NULL, 2882 &futex_shift, NULL,
2862 futex_hashsize, futex_hashsize); 2883 futex_hashsize, futex_hashsize);
2863 futex_hashsize = 1UL << futex_shift; 2884 futex_hashsize = 1UL << futex_shift;
2864 /* 2885
2865 * This will fail and we want it. Some arch implementations do 2886 futex_detect_cmpxchg();
2866 * runtime detection of the futex_atomic_cmpxchg_inatomic()
2867 * functionality. We want to know that before we call in any
2868 * of the complex code paths. Also we want to prevent
2869 * registration of robust lists in that case. NULL is
2870 * guaranteed to fault and we get -EFAULT on functional
2871 * implementation, the non-functional ones will return
2872 * -ENOSYS.
2873 */
2874 if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT)
2875 futex_cmpxchg_enabled = 1;
2876 2887
2877 for (i = 0; i < futex_hashsize; i++) { 2888 for (i = 0; i < futex_hashsize; i++) {
2878 plist_head_init(&futex_queues[i].chain); 2889 plist_head_init(&futex_queues[i].chain);