History

futex: Allow for compiling out PI support

This makes it possible to preserve basic futex support and compile out the PI support when RT mutexes are not available.

Nicolas Pitre committed 9 years ago

Commit bc2eecd1 parent f06e8c54 files · +63 −2Browse files

Unified · Split

4 files
  1. include/linux/futex.h +6 −1
  2. init/Kconfig +6 −1
  3. kernel/futex.c +22 −0
  4. kernel/locking/rtmutex_common.h +29 −0
include/linux/futex.h+6−1
@@ -54,7 +54,6 @@ union futex_key { · 53 unmodified lines
54 54
55#ifdef CONFIG_FUTEX55#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);
58#ifdef CONFIG_HAVE_FUTEX_CMPXCHG57#ifdef CONFIG_HAVE_FUTEX_CMPXCHG
59#define futex_cmpxchg_enabled 158#define futex_cmpxchg_enabled 1
60#else59#else
@@ -64,8 +63,14 @@ extern int futex_cmpxchg_enabled; · 3 unmodified lines
64static inline void exit_robust_list(struct task_struct *curr)63static inline void exit_robust_list(struct task_struct *curr)
65{64{
66}65}
66#endif
67
68#ifdef CONFIG_FUTEX_PI
69extern void exit_pi_state_list(struct task_struct *curr);
70#else
67static inline void exit_pi_state_list(struct task_struct *curr)71static inline void exit_pi_state_list(struct task_struct *curr)
68{72{
69}73}
70#endif74#endif
75
71#endif76#endif
init/Kconfig+6−1
@@ -1275,12 +1275,17 @@ config BASE_FULL · 1274 unmodified lines
1275config FUTEX1275config FUTEX
1276 bool "Enable futex support" if EXPERT1276 bool "Enable futex support" if EXPERT
1277 default y1277 default y
1278 select RT_MUTEXES1278 imply RT_MUTEXES
1279 help1279 help
1280 Disabling this option will cause the kernel to be built without1280 Disabling this option will cause the kernel to be built without
1281 support for "fast userspace mutexes". The resulting kernel may not1281 support for "fast userspace mutexes". The resulting kernel may not
1282 run glibc-based applications correctly.1282 run glibc-based applications correctly.
1283 1283
1284config FUTEX_PI
1285 bool
1286 depends on FUTEX && RT_MUTEXES
1287 default y
1288
1284config HAVE_FUTEX_CMPXCHG1289config HAVE_FUTEX_CMPXCHG
1285 bool1290 bool
1286 depends on FUTEX1291 depends on FUTEX
kernel/futex.c+22−0
@@ -875,6 +875,8 @@ static struct task_struct *futex_find_get_task(pid_t pid) · 874 unmodified lines
875 return p;875 return p;
876}876}
877 877
878#ifdef CONFIG_FUTEX_PI
879
878/*880/*
879 * This task is holding PI mutexes at exit time => bad.881 * This task is holding PI mutexes at exit time => bad.
880 * Kernel cleans up PI-state, but userspace is likely hosed.882 * Kernel cleans up PI-state, but userspace is likely hosed.
@@ -932,6 +934,8 @@ void exit_pi_state_list(struct task_struct *curr) · 51 unmodified lines
932 raw_spin_unlock_irq(&curr->pi_lock);934 raw_spin_unlock_irq(&curr->pi_lock);
933}935}
934 936
937#endif
938
935/*939/*
936 * We need to check the following states:940 * We need to check the following states:
937 *941 *
@@ -1799,6 +1803,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, · 861 unmodified lines
1799 struct futex_q *this, *next;1803 struct futex_q *this, *next;
1800 DEFINE_WAKE_Q(wake_q);1804 DEFINE_WAKE_Q(wake_q);
1801 1805
1806 /*
1807 * When PI not supported: return -ENOSYS if requeue_pi is true,
1808 * consequently the compiler knows requeue_pi is always false past
1809 * this point which will optimize away all the conditional code
1810 * further down.
1811 */
1812 if (!IS_ENABLED(CONFIG_FUTEX_PI) && requeue_pi)
1813 return -ENOSYS;
1814
1802 if (requeue_pi) {1815 if (requeue_pi) {
1803 /*1816 /*
1804 * Requeue PI only works on two distinct uaddrs. This1817 * Requeue PI only works on two distinct uaddrs. This
@@ -2594,6 +2607,9 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, · 789 unmodified lines
2594 struct futex_q q = futex_q_init;2607 struct futex_q q = futex_q_init;
2595 int res, ret;2608 int res, ret;
2596 2609
2610 if (!IS_ENABLED(CONFIG_FUTEX_PI))
2611 return -ENOSYS;
2612
2597 if (refill_pi_state_cache())2613 if (refill_pi_state_cache())
2598 return -ENOMEM;2614 return -ENOMEM;
2599 2615
@@ -2773,6 +2789,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) · 173 unmodified lines
2773 struct futex_q *top_waiter;2789 struct futex_q *top_waiter;
2774 int ret;2790 int ret;
2775 2791
2792 if (!IS_ENABLED(CONFIG_FUTEX_PI))
2793 return -ENOSYS;
2794
2776retry:2795retry:
2777 if (get_user(uval, uaddr))2796 if (get_user(uval, uaddr))
2778 return -EFAULT;2797 return -EFAULT;
@@ -2983,6 +3002,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, · 204 unmodified lines
2983 struct futex_q q = futex_q_init;3002 struct futex_q q = futex_q_init;
2984 int res, ret;3003 int res, ret;
2985 3004
3005 if (!IS_ENABLED(CONFIG_FUTEX_PI))
3006 return -ENOSYS;
3007
2986 if (uaddr == uaddr2)3008 if (uaddr == uaddr2)
2987 return -EINVAL;3009 return -EINVAL;
2988 3010
kernel/locking/rtmutex_common.h+29−0
@@ -40,6 +40,9 @@ struct rt_mutex_waiter { · 39 unmodified lines
40/*40/*
41 * Various helpers to access the waiters-tree:41 * Various helpers to access the waiters-tree:
42 */42 */
43
44#ifdef CONFIG_RT_MUTEXES
45
43static inline int rt_mutex_has_waiters(struct rt_mutex *lock)46static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
44{47{
45 return !RB_EMPTY_ROOT(&lock->waiters);48 return !RB_EMPTY_ROOT(&lock->waiters);
@@ -69,6 +72,32 @@ task_top_pi_waiter(struct task_struct *p) · 23 unmodified lines
69 pi_tree_entry);72 pi_tree_entry);
70}73}
71 74
75#else
76
77static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
78{
79 return false;
80}
81
82static inline struct rt_mutex_waiter *
83rt_mutex_top_waiter(struct rt_mutex *lock)
84{
85 return NULL;
86}
87
88static inline int task_has_pi_waiters(struct task_struct *p)
89{
90 return false;
91}
92
93static inline struct rt_mutex_waiter *
94task_top_pi_waiter(struct task_struct *p)
95{
96 return NULL;
97}
98
99#endif
100
72/*101/*
73 * lock->owner state tracking:102 * lock->owner state tracking:
74 */103 */