summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-11-08 09:56:37 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-11-08 09:56:37 -0800
commitaaaaa7ecdc0b46fe56e8192545321ce44d85236e (patch)
tree308d7f6d5c9ac5d1aa20cdce8d8f7329f785e0da /kernel
parent15a9844458cf3a7afcd720eca81ecb3a16213cb4 (diff)
parent9f5d1c336a10c0d24e83e40b4c1b9539f7dba627 (diff)
Merge tag 'locking-urgent-2020-11-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull futex fix from Thomas Gleixner: "A single fix for the futex code where an intermediate state in the underlying RT mutex was not handled correctly and triggering a BUG() instead of treating it as another variant of retry condition" * tag 'locking-urgent-2020-11-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: futex: Handle transient "ownerless" rtmutex state correctly
Diffstat (limited to 'kernel')
-rw-r--r--kernel/futex.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index f8614ef4ff31..ac328874f6e5 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -2380,10 +2380,22 @@ retry:
}
/*
- * Since we just failed the trylock; there must be an owner.
+ * The trylock just failed, so either there is an owner or
+ * there is a higher priority waiter than this one.
*/
newowner = rt_mutex_owner(&pi_state->pi_mutex);
- BUG_ON(!newowner);
+ /*
+ * If the higher priority waiter has not yet taken over the
+ * rtmutex then newowner is NULL. We can't return here with
+ * that state because it's inconsistent vs. the user space
+ * state. So drop the locks and try again. It's a valid
+ * situation and not any different from the other retry
+ * conditions.
+ */
+ if (unlikely(!newowner)) {
+ err = -EAGAIN;
+ goto handle_err;
+ }
} else {
WARN_ON_ONCE(argowner != current);
if (oldowner == current) {