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)
627
627
}
628
628
629
629
/*
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.
632
632
*/
633
633
void futex_unqueue_pi (struct futex_q * q )
634
634
{
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 );
636
645
637
646
BUG_ON (!q -> pi_state );
638
647
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)
1135
1135
1136
1136
hb = futex_hash (& key );
1137
1137
spin_lock (& hb -> lock );
1138
+ retry_hb :
1138
1139
1139
1140
/*
1140
1141
* 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)
1177
1178
/*
1178
1179
* Futex vs rt_mutex waiter state -- if there are no rt_mutex
1179
1180
* 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.
1181
1186
*/
1182
1187
rt_waiter = rt_mutex_top_waiter (& pi_state -> pi_mutex );
1183
1188
if (!rt_waiter ) {
1189
+ __futex_unqueue (top_waiter );
1184
1190
raw_spin_unlock_irq (& pi_state -> pi_mutex .wait_lock );
1185
- goto do_uncontended ;
1191
+ goto retry_hb ;
1186
1192
}
1187
1193
1188
1194
get_pi_state (pi_state );
@@ -1217,7 +1223,6 @@ int futex_unlock_pi(u32 __user *uaddr, unsigned int flags)
1217
1223
return ret ;
1218
1224
}
1219
1225
1220
- do_uncontended :
1221
1226
/*
1222
1227
* We have no kernel internal state, i.e. no waiters in the
1223
1228
* kernel. Waiters which are about to queue themselves are stuck
You can’t perform that action at this time.
0 commit comments