Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc2eecd7 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Thomas Gleixner
Browse files

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: default avatarNicolas Pitre <nico@linaro.org>
Signed-off-by: default avatarThomas 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
parent f06e8c58
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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
+6 −1
Original line number Diff line number Diff line
@@ -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
+22 −0
Original line number Diff line number Diff line
@@ -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;

+29 −0
Original line number Diff line number Diff line
@@ -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:
 */