summaryrefslogtreecommitdiff
path: root/kernel/futex/core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2024-02-01 17:45:32 +0000
committerMark Brown <broonie@kernel.org>2024-02-01 17:45:32 +0000
commite81fdba0208666b65bafeaba814874b4d6e5edde (patch)
tree5de26e8be4ca1801ca27bffe25c129d29b13dba9 /kernel/futex/core.c
parent5513c5d0fb3d509cdd0a11afc18441c57eb7c94c (diff)
parent28876c1ae8b8cd1dacef50bd6c0555824774f0d2 (diff)
ALSA: Various fixes for Cirrus Logic CS35L56 support
Merge series from Richard Fitzgerald <rf@opensource.cirrus.com>: These patches fixe various things that were undocumented, unknown or uncertain when the original driver code was written. And also a few things that were just bugs.
Diffstat (limited to 'kernel/futex/core.c')
-rw-r--r--kernel/futex/core.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index e0e853412c15..1e78ef24321e 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -627,12 +627,21 @@ retry:
}
/*
- * PI futexes can not be requeued and must remove themselves from the
- * hash bucket. The hash bucket lock (i.e. lock_ptr) is held.
+ * PI futexes can not be requeued and must remove themselves from the hash
+ * bucket. The hash bucket lock (i.e. lock_ptr) is held.
*/
void futex_unqueue_pi(struct futex_q *q)
{
- __futex_unqueue(q);
+ /*
+ * If the lock was not acquired (due to timeout or signal) then the
+ * rt_waiter is removed before futex_q is. If this is observed by
+ * an unlocker after dropping the rtmutex wait lock and before
+ * acquiring the hash bucket lock, then the unlocker dequeues the
+ * futex_q from the hash bucket list to guarantee consistent state
+ * vs. userspace. Therefore the dequeue here must be conditional.
+ */
+ if (!plist_node_empty(&q->list))
+ __futex_unqueue(q);
BUG_ON(!q->pi_state);
put_pi_state(q->pi_state);