|
@@ -647,8 +647,14 @@ static struct futex_pi_state * alloc_pi_state(void)
|
|
|
return pi_state;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Must be called with the hb lock held.
|
|
|
+ */
|
|
|
static void free_pi_state(struct futex_pi_state *pi_state)
|
|
|
{
|
|
|
+ if (!pi_state)
|
|
|
+ return;
|
|
|
+
|
|
|
if (!atomic_dec_and_test(&pi_state->refcount))
|
|
|
return;
|
|
|
|
|
@@ -1527,15 +1533,6 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
|
|
|
}
|
|
|
|
|
|
retry:
|
|
|
- if (pi_state != NULL) {
|
|
|
- /*
|
|
|
- * We will have to lookup the pi_state again, so free this one
|
|
|
- * to keep the accounting correct.
|
|
|
- */
|
|
|
- free_pi_state(pi_state);
|
|
|
- pi_state = NULL;
|
|
|
- }
|
|
|
-
|
|
|
ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ);
|
|
|
if (unlikely(ret != 0))
|
|
|
goto out;
|
|
@@ -1625,6 +1622,8 @@ retry_private:
|
|
|
case 0:
|
|
|
break;
|
|
|
case -EFAULT:
|
|
|
+ free_pi_state(pi_state);
|
|
|
+ pi_state = NULL;
|
|
|
double_unlock_hb(hb1, hb2);
|
|
|
hb_waiters_dec(hb2);
|
|
|
put_futex_key(&key2);
|
|
@@ -1640,6 +1639,8 @@ retry_private:
|
|
|
* exit to complete.
|
|
|
* - The user space value changed.
|
|
|
*/
|
|
|
+ free_pi_state(pi_state);
|
|
|
+ pi_state = NULL;
|
|
|
double_unlock_hb(hb1, hb2);
|
|
|
hb_waiters_dec(hb2);
|
|
|
put_futex_key(&key2);
|
|
@@ -1716,6 +1717,7 @@ retry_private:
|
|
|
}
|
|
|
|
|
|
out_unlock:
|
|
|
+ free_pi_state(pi_state);
|
|
|
double_unlock_hb(hb1, hb2);
|
|
|
hb_waiters_dec(hb2);
|
|
|
|
|
@@ -1733,8 +1735,6 @@ out_put_keys:
|
|
|
out_put_key1:
|
|
|
put_futex_key(&key1);
|
|
|
out:
|
|
|
- if (pi_state != NULL)
|
|
|
- free_pi_state(pi_state);
|
|
|
return ret ? ret : task_count;
|
|
|
}
|
|
|
|