futex: Allow for compiling out PI support
authorNicolas Pitre <nicolas.pitre@linaro.org>
Tue, 1 Aug 2017 04:31:32 +0000 (00:31 -0400)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 1 Aug 2017 12:36:35 +0000 (14:36 +0200)
This makes it possible to preserve basic futex support and compile out the
PI support when RT mutexes are not available.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Darren Hart <dvhart@infradead.org>
Link: http://lkml.kernel.org/r/alpine.LFD.2.20.1708010024190.5981@knanqh.ubzr
include/linux/futex.h
init/Kconfig
kernel/futex.c
kernel/locking/rtmutex_common.h

index 7c5b694864cd9a52d3c5cd4496e834c4e8c5e7aa..f36bfd26f998a7daccdb4f271c7c3300f567b2a9 100644 (file)
@@ -54,7 +54,6 @@ union futex_key {
 
 #ifdef CONFIG_FUTEX
 extern void exit_robust_list(struct task_struct *curr);
-extern void exit_pi_state_list(struct task_struct *curr);
 #ifdef CONFIG_HAVE_FUTEX_CMPXCHG
 #define futex_cmpxchg_enabled 1
 #else
@@ -64,8 +63,14 @@ extern int futex_cmpxchg_enabled;
 static inline void exit_robust_list(struct task_struct *curr)
 {
 }
+#endif
+
+#ifdef CONFIG_FUTEX_PI
+extern void exit_pi_state_list(struct task_struct *curr);
+#else
 static inline void exit_pi_state_list(struct task_struct *curr)
 {
 }
 #endif
+
 #endif
index 8514b25db21c6bb6928a6944cc6867ae9414321c..5f0ef850e8089339e801d19426fecb7f525d9c7d 100644 (file)
@@ -1275,12 +1275,17 @@ config BASE_FULL
 config FUTEX
        bool "Enable futex support" if EXPERT
        default y
-       select RT_MUTEXES
+       imply RT_MUTEXES
        help
          Disabling this option will cause the kernel to be built without
          support for "fast userspace mutexes".  The resulting kernel may not
          run glibc-based applications correctly.
 
+config FUTEX_PI
+       bool
+       depends on FUTEX && RT_MUTEXES
+       default y
+
 config HAVE_FUTEX_CMPXCHG
        bool
        depends on FUTEX
index 16dbe4c938953a70a49faf0a5264af8c19a9491f..ad0af4df1b9d6bbbe1d27c7bcc55878f2c591fc9 100644 (file)
@@ -875,6 +875,8 @@ static struct task_struct *futex_find_get_task(pid_t pid)
        return p;
 }
 
+#ifdef CONFIG_FUTEX_PI
+
 /*
  * This task is holding PI mutexes at exit time => bad.
  * Kernel cleans up PI-state, but userspace is likely hosed.
@@ -932,6 +934,8 @@ void exit_pi_state_list(struct task_struct *curr)
        raw_spin_unlock_irq(&curr->pi_lock);
 }
 
+#endif
+
 /*
  * We need to check the following states:
  *
@@ -1799,6 +1803,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
        struct futex_q *this, *next;
        DEFINE_WAKE_Q(wake_q);
 
+       /*
+        * When PI not supported: return -ENOSYS if requeue_pi is true,
+        * consequently the compiler knows requeue_pi is always false past
+        * this point which will optimize away all the conditional code
+        * further down.
+        */
+       if (!IS_ENABLED(CONFIG_FUTEX_PI) && requeue_pi)
+               return -ENOSYS;
+
        if (requeue_pi) {
                /*
                 * Requeue PI only works on two distinct uaddrs. This
@@ -2594,6 +2607,9 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags,
        struct futex_q q = futex_q_init;
        int res, ret;
 
+       if (!IS_ENABLED(CONFIG_FUTEX_PI))
+               return -ENOSYS;
+
        if (refill_pi_state_cache())
                return -ENOMEM;
 
@@ -2773,6 +2789,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags)
        struct futex_q *top_waiter;
        int ret;
 
+       if (!IS_ENABLED(CONFIG_FUTEX_PI))
+               return -ENOSYS;
+
 retry:
        if (get_user(uval, uaddr))
                return -EFAULT;
@@ -2983,6 +3002,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
        struct futex_q q = futex_q_init;
        int res, ret;
 
+       if (!IS_ENABLED(CONFIG_FUTEX_PI))
+               return -ENOSYS;
+
        if (uaddr == uaddr2)
                return -EINVAL;
 
index 72ad45a9a79439c53f73afee4ab87330957a0ff2..8d039b928d610932206f49babe739bacda5b0c15 100644 (file)
@@ -40,6 +40,9 @@ struct rt_mutex_waiter {
 /*
  * Various helpers to access the waiters-tree:
  */
+
+#ifdef CONFIG_RT_MUTEXES
+
 static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
 {
        return !RB_EMPTY_ROOT(&lock->waiters);
@@ -69,6 +72,32 @@ task_top_pi_waiter(struct task_struct *p)
                        pi_tree_entry);
 }
 
+#else
+
+static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
+{
+       return false;
+}
+
+static inline struct rt_mutex_waiter *
+rt_mutex_top_waiter(struct rt_mutex *lock)
+{
+       return NULL;
+}
+
+static inline int task_has_pi_waiters(struct task_struct *p)
+{
+       return false;
+}
+
+static inline struct rt_mutex_waiter *
+task_top_pi_waiter(struct task_struct *p)
+{
+       return NULL;
+}
+
+#endif
+
 /*
  * lock->owner state tracking:
  */