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
5454
5555 #ifdef CONFIG_FUTEX
5656 extern void exit_robust_list(struct task_struct *curr);
57−extern void exit_pi_state_list(struct task_struct *curr);
5857 #ifdef CONFIG_HAVE_FUTEX_CMPXCHG
5958 #define futex_cmpxchg_enabled 1
6059 #else
@@ -64,8 +63,14 @@ extern int futex_cmpxchg_enabled; · 3 unmodified lines
6463 static inline void exit_robust_list(struct task_struct *curr)
6564 {
6665 }
66+#endif
67+
68+#ifdef CONFIG_FUTEX_PI
69+extern void exit_pi_state_list(struct task_struct *curr);
70+#else
6771 static inline void exit_pi_state_list(struct task_struct *curr)
6872 {
6973 }
7074 #endif
75+
7176 #endif
init/Kconfig+6−1
@@ -1275,12 +1275,17 @@ config BASE_FULL · 1274 unmodified lines
12751275 config FUTEX
12761276 bool "Enable futex support" if EXPERT
12771277 default y
1278− select RT_MUTEXES
1278+ imply RT_MUTEXES
12791279 help
12801280 Disabling this option will cause the kernel to be built without
12811281 support for "fast userspace mutexes". The resulting kernel may not
12821282 run glibc-based applications correctly.
12831283
1284+config FUTEX_PI
1285+ bool
1286+ depends on FUTEX && RT_MUTEXES
1287+ default y
1288+
12841289 config HAVE_FUTEX_CMPXCHG
12851290 bool
12861291 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
875875 return p;
876876 }
877877
878+#ifdef CONFIG_FUTEX_PI
879+
878880 /*
879881 * This task is holding PI mutexes at exit time => bad.
880882 * 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
932934 raw_spin_unlock_irq(&curr->pi_lock);
933935 }
934936
937+#endif
938+
935939 /*
936940 * We need to check the following states:
937941 *
@@ -1799,6 +1803,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, · 861 unmodified lines
17991803 struct futex_q *this, *next;
18001804 DEFINE_WAKE_Q(wake_q);
18011805
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+
18021815 if (requeue_pi) {
18031816 /*
18041817 * 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
25942607 struct futex_q q = futex_q_init;
25952608 int res, ret;
25962609
2610+ if (!IS_ENABLED(CONFIG_FUTEX_PI))
2611+ return -ENOSYS;
2612+
25972613 if (refill_pi_state_cache())
25982614 return -ENOMEM;
25992615
@@ -2773,6 +2789,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) · 173 unmodified lines
27732789 struct futex_q *top_waiter;
27742790 int ret;
27752791
2792+ if (!IS_ENABLED(CONFIG_FUTEX_PI))
2793+ return -ENOSYS;
2794+
27762795 retry:
27772796 if (get_user(uval, uaddr))
27782797 return -EFAULT;
@@ -2983,6 +3002,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, · 204 unmodified lines
29833002 struct futex_q q = futex_q_init;
29843003 int res, ret;
29853004
3005+ if (!IS_ENABLED(CONFIG_FUTEX_PI))
3006+ return -ENOSYS;
3007+
29863008 if (uaddr == uaddr2)
29873009 return -EINVAL;
29883010
kernel/locking/rtmutex_common.h+29−0
@@ -40,6 +40,9 @@ struct rt_mutex_waiter { · 39 unmodified lines
4040 /*
4141 * Various helpers to access the waiters-tree:
4242 */
43+
44+#ifdef CONFIG_RT_MUTEXES
45+
4346 static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
4447 {
4548 return !RB_EMPTY_ROOT(&lock->waiters);
@@ -69,6 +72,32 @@ task_top_pi_waiter(struct task_struct *p) · 23 unmodified lines
6972 pi_tree_entry);
7073 }
7174
75+#else
76+
77+static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
78+{
79+ return false;
80+}
81+
82+static inline struct rt_mutex_waiter *
83+rt_mutex_top_waiter(struct rt_mutex *lock)
84+{
85+ return NULL;
86+}
87+
88+static inline int task_has_pi_waiters(struct task_struct *p)
89+{
90+ return false;
91+}
92+
93+static inline struct rt_mutex_waiter *
94+task_top_pi_waiter(struct task_struct *p)
95+{
96+ return NULL;
97+}
98+
99+#endif
100+
72101 /*
73102 * lock->owner state tracking:
74103 */