summaryrefslogtreecommitdiff
path: root/kernel/futex/pi.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2024-02-01 14:33:26 -0800
committerJakub Kicinski <kuba@kernel.org>2024-02-01 15:12:37 -0800
commitcf244463a286ea57ea7e63c33614d302f776e62e (patch)
treecaa068596cbfea621376822e30ab545c6516b2c7 /kernel/futex/pi.c
parentcacfd6bfc381ce0e71dfb4ab902ca0fb0e1abe0f (diff)
parent41b9fb381a486360b2daaec0c7480f8e3ff72bc7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR. No conflicts or adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'kernel/futex/pi.c')
-rw-r--r--kernel/futex/pi.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/kernel/futex/pi.c b/kernel/futex/pi.c
index 90e5197f4e56..5722467f2737 100644
--- a/kernel/futex/pi.c
+++ b/kernel/futex/pi.c
@@ -1135,6 +1135,7 @@ retry:
hb = futex_hash(&key);
spin_lock(&hb->lock);
+retry_hb:
/*
* Check waiters first. We do not trust user space values at
@@ -1177,12 +1178,17 @@ retry:
/*
* Futex vs rt_mutex waiter state -- if there are no rt_mutex
* waiters even though futex thinks there are, then the waiter
- * is leaving and the uncontended path is safe to take.
+ * is leaving. The entry needs to be removed from the list so a
+ * new futex_lock_pi() is not using this stale PI-state while
+ * the futex is available in user space again.
+ * There can be more than one task on its way out so it needs
+ * to retry.
*/
rt_waiter = rt_mutex_top_waiter(&pi_state->pi_mutex);
if (!rt_waiter) {
+ __futex_unqueue(top_waiter);
raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
- goto do_uncontended;
+ goto retry_hb;
}
get_pi_state(pi_state);
@@ -1217,7 +1223,6 @@ retry:
return ret;
}
-do_uncontended:
/*
* We have no kernel internal state, i.e. no waiters in the
* kernel. Waiters which are about to queue themselves are stuck