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: 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
This commit is contained in:
parent
f06e8c584f
commit
bc2eecd7ec
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue