diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index b766d28accd6..64c38115c7b6 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -1556,10 +1556,10 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, | |||
1556 | 1556 | ||
1557 | /* | 1557 | /* |
1558 | * We are here either because we stole the rtmutex from the | 1558 | * We are here either because we stole the rtmutex from the |
1559 | * pending owner or we are the pending owner which failed to | 1559 | * previous highest priority waiter or we are the highest priority |
1560 | * get the rtmutex. We have to replace the pending owner TID | 1560 | * waiter but failed to get the rtmutex the first time. |
1561 | * in the user space variable. This must be atomic as we have | 1561 | * We have to replace the newowner TID in the user space variable. |
1562 | * to preserve the owner died bit here. | 1562 | * This must be atomic as we have to preserve the owner died bit here. |
1563 | * | 1563 | * |
1564 | * Note: We write the user space value _before_ changing the pi_state | 1564 | * Note: We write the user space value _before_ changing the pi_state |
1565 | * because we can fault here. Imagine swapped out pages or a fork | 1565 | * because we can fault here. Imagine swapped out pages or a fork |
@@ -1608,8 +1608,8 @@ retry: | |||
1608 | 1608 | ||
1609 | /* | 1609 | /* |
1610 | * To handle the page fault we need to drop the hash bucket | 1610 | * To handle the page fault we need to drop the hash bucket |
1611 | * lock here. That gives the other task (either the pending | 1611 | * lock here. That gives the other task (either the highest priority |
1612 | * owner itself or the task which stole the rtmutex) the | 1612 | * waiter itself or the task which stole the rtmutex) the |
1613 | * chance to try the fixup of the pi_state. So once we are | 1613 | * chance to try the fixup of the pi_state. So once we are |
1614 | * back from handling the fault we need to check the pi_state | 1614 | * back from handling the fault we need to check the pi_state |
1615 | * after reacquiring the hash bucket lock and before trying to | 1615 | * after reacquiring the hash bucket lock and before trying to |
@@ -1685,18 +1685,20 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) | |||
1685 | /* | 1685 | /* |
1686 | * pi_state is incorrect, some other task did a lock steal and | 1686 | * pi_state is incorrect, some other task did a lock steal and |
1687 | * we returned due to timeout or signal without taking the | 1687 | * we returned due to timeout or signal without taking the |
1688 | * rt_mutex. Too late. We can access the rt_mutex_owner without | 1688 | * rt_mutex. Too late. |
1689 | * locking, as the other task is now blocked on the hash bucket | ||
1690 | * lock. Fix the state up. | ||
1691 | */ | 1689 | */ |
1690 | raw_spin_lock(&q->pi_state->pi_mutex.wait_lock); | ||
1692 | owner = rt_mutex_owner(&q->pi_state->pi_mutex); | 1691 | owner = rt_mutex_owner(&q->pi_state->pi_mutex); |
1692 | if (!owner) | ||
1693 | owner = rt_mutex_next_owner(&q->pi_state->pi_mutex); | ||
1694 | raw_spin_unlock(&q->pi_state->pi_mutex.wait_lock); | ||
1693 | ret = fixup_pi_state_owner(uaddr, q, owner); | 1695 | ret = fixup_pi_state_owner(uaddr, q, owner); |
1694 | goto out; | 1696 | goto out; |
1695 | } | 1697 | } |
1696 | 1698 | ||
1697 | /* | 1699 | /* |
1698 | * Paranoia check. If we did not take the lock, then we should not be | 1700 | * Paranoia check. If we did not take the lock, then we should not be |
1699 | * the owner, nor the pending owner, of the rt_mutex. | 1701 | * the owner of the rt_mutex. |
1700 | */ | 1702 | */ |
1701 | if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) | 1703 | if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) |
1702 | printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " | 1704 | printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " |