History

futex: Clarify futex_requeue() PI handling

When requeuing to a PI futex, then the requeue code tries to trylock the PI futex on behalf of the topmost waiter on the inner 'waitqueue' futex. If that succeeds, then PI state has to be allocated in order to requeue further waiters to the PI futex. The comment and the code are confusing, as the PI state allocation uses lookup_pi_state(), which either attaches to an existing waiter or to the owner. As the PI futex was just acquired, there cannot be a waiter on the PI futex because the hash bucket lock is held. Clarify the comment and use attach_to_pi_owner() directly. As the task on which behalf the PI futex has been acquired is guaranteed to be alive and not exiting, this call must succeed. Add a WARN_ON() in case that fails.

Thomas Gleixner committed 5 years ago

Commit f6f4ec01 parent c363b7e1 file · +23 −38Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/futex.c+23−38
@@ -1299,27 +1299,6 @@ static int attach_to_pi_owner(u32 __user *uaddr, u32 uval, union futex_key *key, · 1298 unmodified lines
1299 return 0;1299 return 0;
1300}1300}
1301 1301
1302static int lookup_pi_state(u32 __user *uaddr, u32 uval,
1303 struct futex_hash_bucket *hb,
1304 union futex_key *key, struct futex_pi_state **ps,
1305 struct task_struct **exiting)
1306{
1307 struct futex_q *top_waiter = futex_top_waiter(hb, key);
1308
1309 /*
1310 * If there is a waiter on that futex, validate it and
1311 * attach to the pi_state when the validation succeeds.
1312 */
1313 if (top_waiter)
1314 return attach_to_pi_state(uaddr, uval, top_waiter->pi_state, ps);
1315
1316 /*
1317 * We are the first waiter - try to look up the owner based on
1318 * @uval and attach to it.
1319 */
1320 return attach_to_pi_owner(uaddr, uval, key, ps, exiting);
1321}
1322
1323static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval)1302static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval)
1324{1303{
1325 int err;1304 int err;
@@ -2038,8 +2017,8 @@ retry_private: · 712 unmodified lines
2038 * At this point the top_waiter has either taken uaddr2 or is2017 * At this point the top_waiter has either taken uaddr2 or is
2039 * waiting on it. If the former, then the pi_state will not2018 * waiting on it. If the former, then the pi_state will not
2040 * exist yet, look it up one more time to ensure we have a2019 * exist yet, look it up one more time to ensure we have a
2041 * reference to it. If the lock was taken, ret contains the2020 * reference to it. If the lock was taken, @ret contains the
2042 * vpid of the top waiter task.2021 * VPID of the top waiter task.
2043 * If the lock was not taken, we have pi_state and an initial2022 * If the lock was not taken, we have pi_state and an initial
2044 * refcount on it. In case of an error we have nothing.2023 * refcount on it. In case of an error we have nothing.
2045 */2024 */
@@ -2047,19 +2026,25 @@ retry_private: · 1 unmodified line
2047 WARN_ON(pi_state);2026 WARN_ON(pi_state);
2048 task_count++;2027 task_count++;
2049 /*2028 /*
2050 * If we acquired the lock, then the user space value2029 * If futex_proxy_trylock_atomic() acquired the
2051 * of uaddr2 should be vpid. It cannot be changed by2030 * user space futex, then the user space value
2052 * the top waiter as it is blocked on hb2 lock if it2031 * @uaddr2 has been set to the @hb1's top waiter
2053 * tries to do so. If something fiddled with it behind2032 * task VPID. This task is guaranteed to be alive
2054 * our back the pi state lookup might unearth it. So2033 * and cannot be exiting because it is either
2055 * we rather use the known value than rereading and2034 * sleeping or blocked on @hb2 lock.
2056 * handing potential crap to lookup_pi_state.2035 *
2036 * The @uaddr2 futex cannot have waiters either as
2037 * otherwise futex_proxy_trylock_atomic() would not
2038 * have succeeded.
2057 *2039 *
2058 * If that call succeeds then we have pi_state and an2040 * In order to requeue waiters to @hb2, pi state is
2059 * initial refcount on it.2041 * required. Hand in the VPID value (@ret) and
2042 * allocate PI state with an initial refcount on
2043 * it.
2060 */2044 */
2061 ret = lookup_pi_state(uaddr2, ret, hb2, &key2,2045 ret = attach_to_pi_owner(uaddr2, ret, &key2, &pi_state,
2062 &pi_state, &exiting);2046 &exiting);
2047 WARN_ON(ret);
2063 }2048 }
2064 2049
2065 switch (ret) {2050 switch (ret) {
@@ -2183,9 +2168,9 @@ retry_private: · 117 unmodified lines
2183 }2168 }
2184 2169
2185 /*2170 /*
2186 * We took an extra initial reference to the pi_state either2171 * We took an extra initial reference to the pi_state either in
2187 * in futex_proxy_trylock_atomic() or in lookup_pi_state(). We2172 * futex_proxy_trylock_atomic() or in attach_to_pi_owner(). We need
2188 * need to drop it here again.2173 * to drop it here again.
2189 */2174 */
2190 put_pi_state(pi_state);2175 put_pi_state(pi_state);
2191 2176
@@ -2364,7 +2349,7 @@ static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, · 172 unmodified lines
2364 * Modifying pi_state _before_ the user space value would leave the2349 * Modifying pi_state _before_ the user space value would leave the
2365 * pi_state in an inconsistent state when we fault here, because we2350 * pi_state in an inconsistent state when we fault here, because we
2366 * need to drop the locks to handle the fault. This might be observed2351 * need to drop the locks to handle the fault. This might be observed
2367 * in the PID check in lookup_pi_state.2352 * in the PID checks when attaching to PI state .
2368 */2353 */
2369retry:2354retry:
2370 if (!argowner) {2355 if (!argowner) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t