mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
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
|
#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;
|
|||||||
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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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 {
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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:
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user