Not sure if this the best way to go here, but the patch below seems to resolve
the problem for me
If this is fine, I'll send a separate patch for mainline. Currently mainline
seems to be missing the earlier patch referenced above as well
/**
- * handle_early_requeue_pi_wakeup() - Detect early wakeup on the initial futex
- * @hb: the hash_bucket futex_q was original enqueued on
- * @q: the futex_q woken while waiting to be requeued
- * @key2: the futex_key of the requeue target futex
- * @timeout: the timeout associated with the wait (NULL if none)
- *
- * Detect if the task was woken on the initial futex as opposed to the requeue
- * target futex. If so, determine if it was a timeout or a signal that caused
- * the wakeup and return the appropriate error code to the caller. Must be
- * called with the hb lock held.
- *
- * Returns
- * 0 - no early wakeup detected
- * <0 - -ETIMEDOUT or -ERESTARTNOINTR
- */
-static inline
-int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
- struct futex_q *q, union futex_key *key2,
- struct hrtimer_sleeper *timeout)
-{
spin_unlock(&hb->lock);
+ if (ret == -EAGAIN) {
+ /* Retry on spurious wakeup */
+ put_futex_key(fshared, &q.key);
+ put_futex_key(fshared, &key2);
+ goto retry;
+ }
if (ret)
goto out_put_keys;
@@ -2264,9 +2247,6 @@ out_put_keys:
out_key2:
put_futex_key(fshared, &key2);
- /* Spurious wakeup ? */
- if (ret == -EAGAIN)
- goto retry;