Messages in this thread | | | Date | Tue, 3 Aug 2021 13:20:51 +0200 | From | Peter Zijlstra <> | Subject | Re: [patch 58/63] futex: Prevent requeue_pi() lock nesting issue on RT |
| |
On Fri, Jul 30, 2021 at 03:51:05PM +0200, Thomas Gleixner wrote: > @@ -3082,27 +3302,22 @@ static int futex_unlock_pi(u32 __user *u > } > > /** > - * handle_early_requeue_pi_wakeup() - Detect early wakeup on the initial futex > + * handle_early_requeue_pi_wakeup() - Handle 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. > + * Determine the cause for the early wakeup. > * > * Return: > - * - 0 = no early wakeup detected; > - * - <0 = -ETIMEDOUT or -ERESTARTNOINTR > + * -EWOULDBLOCK or -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 futex_q *q, > struct hrtimer_sleeper *timeout) > { > - int ret = 0; > + int ret; > > /* > * With the hb lock held, we avoid races while we process the wakeup. > @@ -3111,22 +3326,21 @@ int handle_early_requeue_pi_wakeup(struc > * It can't be requeued from uaddr2 to something else since we don't > * support a PI aware source futex for requeue. > */ > - if (!match_futex(&q->key, key2)) { > - WARN_ON(q->lock_ptr && (&hb->lock != q->lock_ptr)); > - /* > - * We were woken prior to requeue by a timeout or a signal. > - * Unqueue the futex_q and determine which it was. > - */ > - plist_del(&q->list, &hb->chain); > - hb_waiters_dec(hb); > + WARN_ON_ONCE(&hb->lock != q->lock_ptr); > > - /* Handle spurious wakeups gracefully */ > - ret = -EWOULDBLOCK; > - if (timeout && !timeout->task) > - ret = -ETIMEDOUT; > - else if (signal_pending(current)) > - ret = -ERESTARTNOINTR; > - } > + /* > + * We were woken prior to requeue by a timeout or a signal. > + * Unqueue the futex_q and determine which it was. > + */ > + plist_del(&q->list, &hb->chain); > + hb_waiters_dec(hb); > + > + /* Handle spurious wakeups gracefully */ > + ret = -EWOULDBLOCK; > + if (timeout && !timeout->task) > + ret = -ETIMEDOUT; > + else if (signal_pending(current)) > + ret = -ERESTARTNOINTR; > return ret; > }
AFAICT this change is a separate cleanup, possible because the only callsite already does that match_futex() test before calling this.
I think it might be worth splitting out, just to reduce the complexity of this patch.
| |