File tree Expand file tree Collapse file tree 2 files changed +20
-6
lines changed Expand file tree Collapse file tree 2 files changed +20
-6
lines changed Original file line number Diff line number Diff line change @@ -627,12 +627,21 @@ int futex_unqueue(struct futex_q *q)
627627}
628628
629629/*
630- * PI futexes can not be requeued and must remove themselves from the
631- * hash bucket. The hash bucket lock (i.e. lock_ptr) is held.
630+ * PI futexes can not be requeued and must remove themselves from the hash
631+ * bucket. The hash bucket lock (i.e. lock_ptr) is held.
632632 */
633633void futex_unqueue_pi (struct futex_q * q )
634634{
635- __futex_unqueue (q );
635+ /*
636+ * If the lock was not acquired (due to timeout or signal) then the
637+ * rt_waiter is removed before futex_q is. If this is observed by
638+ * an unlocker after dropping the rtmutex wait lock and before
639+ * acquiring the hash bucket lock, then the unlocker dequeues the
640+ * futex_q from the hash bucket list to guarantee consistent state
641+ * vs. userspace. Therefore the dequeue here must be conditional.
642+ */
643+ if (!plist_node_empty (& q -> list ))
644+ __futex_unqueue (q );
636645
637646 BUG_ON (!q -> pi_state );
638647 put_pi_state (q -> pi_state );
Original file line number Diff line number Diff line change @@ -1135,6 +1135,7 @@ int futex_unlock_pi(u32 __user *uaddr, unsigned int flags)
11351135
11361136 hb = futex_hash (& key );
11371137 spin_lock (& hb -> lock );
1138+ retry_hb :
11381139
11391140 /*
11401141 * Check waiters first. We do not trust user space values at
@@ -1177,12 +1178,17 @@ int futex_unlock_pi(u32 __user *uaddr, unsigned int flags)
11771178 /*
11781179 * Futex vs rt_mutex waiter state -- if there are no rt_mutex
11791180 * waiters even though futex thinks there are, then the waiter
1180- * is leaving and the uncontended path is safe to take.
1181+ * is leaving. The entry needs to be removed from the list so a
1182+ * new futex_lock_pi() is not using this stale PI-state while
1183+ * the futex is available in user space again.
1184+ * There can be more than one task on its way out so it needs
1185+ * to retry.
11811186 */
11821187 rt_waiter = rt_mutex_top_waiter (& pi_state -> pi_mutex );
11831188 if (!rt_waiter ) {
1189+ __futex_unqueue (top_waiter );
11841190 raw_spin_unlock_irq (& pi_state -> pi_mutex .wait_lock );
1185- goto do_uncontended ;
1191+ goto retry_hb ;
11861192 }
11871193
11881194 get_pi_state (pi_state );
@@ -1217,7 +1223,6 @@ int futex_unlock_pi(u32 __user *uaddr, unsigned int flags)
12171223 return ret ;
12181224 }
12191225
1220- do_uncontended :
12211226 /*
12221227 * We have no kernel internal state, i.e. no waiters in the
12231228 * kernel. Waiters which are about to queue themselves are stuck
You can’t perform that action at this time.
0 commit comments