From: Peter Zijlstra <peterz@xxxxxxxxxxxxx> commit bf92cf3a5100f5a0d5f9834787b130159397cb22 upstream. Add a put_pit_state() as counterpart for get_pi_state() so the refcounting becomes consistent. Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> Cc: juri.lelli@xxxxxxx Cc: bigeasy@xxxxxxxxxxxxx Cc: xlpang@xxxxxxxxxx Cc: rostedt@xxxxxxxxxxx Cc: mathieu.desnoyers@xxxxxxxxxxxx Cc: jdesfossez@xxxxxxxxxxxx Cc: dvhart@xxxxxxxxxxxxx Cc: bristot@xxxxxxxxxx Link: http://lkml.kernel.org/r/20170322104151.801778516@xxxxxxxxxxxxx Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Conflicts: kernel/futex.c Tested-by:Henrik Austad <haustad@xxxxxxxxx> --- kernel/futex.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 52e3678..9d7d462 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -799,7 +799,7 @@ static int refill_pi_state_cache(void) return 0; } -static struct futex_pi_state * alloc_pi_state(void) +static struct futex_pi_state *alloc_pi_state(void) { struct futex_pi_state *pi_state = current->pi_state_cache; @@ -809,6 +809,11 @@ static struct futex_pi_state * alloc_pi_state(void) return pi_state; } +static void get_pi_state(struct futex_pi_state *pi_state) +{ + WARN_ON_ONCE(!atomic_inc_not_zero(&pi_state->refcount)); +} + /* * Must be called with the hb lock held. */ @@ -850,7 +855,7 @@ static void free_pi_state(struct futex_pi_state *pi_state) * Look up the task based on what TID userspace gave us. * We dont trust it. */ -static struct task_struct * futex_find_get_task(pid_t pid) +static struct task_struct *futex_find_get_task(pid_t pid) { struct task_struct *p; @@ -1097,7 +1102,7 @@ static int attach_to_pi_state(u32 __user *uaddr, u32 uval, goto out_einval; out_attach: - atomic_inc(&pi_state->refcount); + get_pi_state(pi_state); raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); *ps = pi_state; return 0; @@ -2019,8 +2024,12 @@ retry_private: * of requeue_pi if we couldn't acquire the lock atomically. */ if (requeue_pi) { - /* Prepare the waiter to take the rt_mutex. */ - atomic_inc(&pi_state->refcount); + /* + * Prepare the waiter to take the rt_mutex. Take a + * refcount on the pi_state and store the pointer in + * the futex_q object of the waiter. + */ + get_pi_state(pi_state); this->pi_state = pi_state; ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex, this->rt_waiter, -- 2.7.4