提交 bc2eecd7 编写于 作者: N Nicolas Pitre 提交者: Thomas Gleixner

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.
Signed-off-by: NNicolas Pitre <nico@linaro.org>
Signed-off-by: NThomas 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
上级 f06e8c58
...@@ -54,7 +54,6 @@ union futex_key { ...@@ -54,7 +54,6 @@ union futex_key {
#ifdef CONFIG_FUTEX #ifdef CONFIG_FUTEX
extern void exit_robust_list(struct task_struct *curr); extern void exit_robust_list(struct task_struct *curr);
extern void exit_pi_state_list(struct task_struct *curr);
#ifdef CONFIG_HAVE_FUTEX_CMPXCHG #ifdef CONFIG_HAVE_FUTEX_CMPXCHG
#define futex_cmpxchg_enabled 1 #define futex_cmpxchg_enabled 1
#else #else
...@@ -64,8 +63,14 @@ extern int futex_cmpxchg_enabled; ...@@ -64,8 +63,14 @@ extern int futex_cmpxchg_enabled;
static inline void exit_robust_list(struct task_struct *curr) 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) static inline void exit_pi_state_list(struct task_struct *curr)
{ {
} }
#endif #endif
#endif #endif
...@@ -1275,12 +1275,17 @@ config BASE_FULL ...@@ -1275,12 +1275,17 @@ config BASE_FULL
config FUTEX config FUTEX
bool "Enable futex support" if EXPERT bool "Enable futex support" if EXPERT
default y default y
select RT_MUTEXES imply RT_MUTEXES
help help
Disabling this option will cause the kernel to be built without Disabling this option will cause the kernel to be built without
support for "fast userspace mutexes". The resulting kernel may not support for "fast userspace mutexes". The resulting kernel may not
run glibc-based applications correctly. run glibc-based applications correctly.
config FUTEX_PI
bool
depends on FUTEX && RT_MUTEXES
default y
config HAVE_FUTEX_CMPXCHG config HAVE_FUTEX_CMPXCHG
bool bool
depends on FUTEX depends on FUTEX
......
...@@ -875,6 +875,8 @@ static struct task_struct *futex_find_get_task(pid_t pid) ...@@ -875,6 +875,8 @@ static struct task_struct *futex_find_get_task(pid_t pid)
return p; return p;
} }
#ifdef CONFIG_FUTEX_PI
/* /*
* This task is holding PI mutexes at exit time => bad. * This task is holding PI mutexes at exit time => bad.
* Kernel cleans up PI-state, but userspace is likely hosed. * Kernel cleans up PI-state, but userspace is likely hosed.
...@@ -932,6 +934,8 @@ void exit_pi_state_list(struct task_struct *curr) ...@@ -932,6 +934,8 @@ void exit_pi_state_list(struct task_struct *curr)
raw_spin_unlock_irq(&curr->pi_lock); raw_spin_unlock_irq(&curr->pi_lock);
} }
#endif
/* /*
* We need to check the following states: * We need to check the following states:
* *
...@@ -1799,6 +1803,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, ...@@ -1799,6 +1803,15 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
struct futex_q *this, *next; struct futex_q *this, *next;
DEFINE_WAKE_Q(wake_q); 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) { if (requeue_pi) {
/* /*
* Requeue PI only works on two distinct uaddrs. This * Requeue PI only works on two distinct uaddrs. This
...@@ -2594,6 +2607,9 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ...@@ -2594,6 +2607,9 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags,
struct futex_q q = futex_q_init; struct futex_q q = futex_q_init;
int res, ret; int res, ret;
if (!IS_ENABLED(CONFIG_FUTEX_PI))
return -ENOSYS;
if (refill_pi_state_cache()) if (refill_pi_state_cache())
return -ENOMEM; return -ENOMEM;
...@@ -2773,6 +2789,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) ...@@ -2773,6 +2789,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags)
struct futex_q *top_waiter; struct futex_q *top_waiter;
int ret; int ret;
if (!IS_ENABLED(CONFIG_FUTEX_PI))
return -ENOSYS;
retry: retry:
if (get_user(uval, uaddr)) if (get_user(uval, uaddr))
return -EFAULT; return -EFAULT;
...@@ -2983,6 +3002,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, ...@@ -2983,6 +3002,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
struct futex_q q = futex_q_init; struct futex_q q = futex_q_init;
int res, ret; int res, ret;
if (!IS_ENABLED(CONFIG_FUTEX_PI))
return -ENOSYS;
if (uaddr == uaddr2) if (uaddr == uaddr2)
return -EINVAL; return -EINVAL;
......
...@@ -40,6 +40,9 @@ struct rt_mutex_waiter { ...@@ -40,6 +40,9 @@ struct rt_mutex_waiter {
/* /*
* Various helpers to access the waiters-tree: * Various helpers to access the waiters-tree:
*/ */
#ifdef CONFIG_RT_MUTEXES
static inline int rt_mutex_has_waiters(struct rt_mutex *lock) static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
{ {
return !RB_EMPTY_ROOT(&lock->waiters); return !RB_EMPTY_ROOT(&lock->waiters);
...@@ -69,6 +72,32 @@ task_top_pi_waiter(struct task_struct *p) ...@@ -69,6 +72,32 @@ task_top_pi_waiter(struct task_struct *p)
pi_tree_entry); 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: * lock->owner state tracking:
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册