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
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -2380,10 +2380,22 @@ retry: · 2379 unmodified lines | ||
| 2380 | 2380 | } |
| 2381 | 2381 | |
| 2382 | 2382 | /* |
| 2383 | − * Since we just failed the trylock; there must be an owner. | |
| 2383 | + * The trylock just failed, so either there is an owner or | |
| 2384 | + * there is a higher priority waiter than this one. | |
| 2384 | 2385 | */ |
| 2385 | 2386 | newowner = rt_mutex_owner(&pi_state->pi_mutex); |
| 2386 | − BUG_ON(!newowner); | |
| 2387 | + /* | |
| 2388 | + * If the higher priority waiter has not yet taken over the | |
| 2389 | + * rtmutex then newowner is NULL. We can't return here with | |
| 2390 | + * that state because it's inconsistent vs. the user space | |
| 2391 | + * state. So drop the locks and try again. It's a valid | |
| 2392 | + * situation and not any different from the other retry | |
| 2393 | + * conditions. | |
| 2394 | + */ | |
| 2395 | + if (unlikely(!newowner)) { | |
| 2396 | + err = -EAGAIN; | |
| 2397 | + goto handle_err; | |
| 2398 | + } | |
| 2387 | 2399 | } else { |
| 2388 | 2400 | WARN_ON_ONCE(argowner != current); |
| 2389 | 2401 | if (oldowner == current) { |