diff options
Diffstat (limited to 'kernel/locking/rtmutex.c')
-rw-r--r-- | kernel/locking/rtmutex.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index b95509416909..28cd09e635ed 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c | |||
@@ -1785,12 +1785,14 @@ int rt_mutex_wait_proxy_lock(struct rt_mutex *lock, | |||
1785 | int ret; | 1785 | int ret; |
1786 | 1786 | ||
1787 | raw_spin_lock_irq(&lock->wait_lock); | 1787 | raw_spin_lock_irq(&lock->wait_lock); |
1788 | |||
1789 | set_current_state(TASK_INTERRUPTIBLE); | ||
1790 | |||
1791 | /* sleep on the mutex */ | 1788 | /* sleep on the mutex */ |
1789 | set_current_state(TASK_INTERRUPTIBLE); | ||
1792 | ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); | 1790 | ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); |
1793 | 1791 | /* | |
1792 | * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might | ||
1793 | * have to fix that up. | ||
1794 | */ | ||
1795 | fixup_rt_mutex_waiters(lock); | ||
1794 | raw_spin_unlock_irq(&lock->wait_lock); | 1796 | raw_spin_unlock_irq(&lock->wait_lock); |
1795 | 1797 | ||
1796 | return ret; | 1798 | return ret; |
@@ -1822,15 +1824,25 @@ bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock, | |||
1822 | 1824 | ||
1823 | raw_spin_lock_irq(&lock->wait_lock); | 1825 | raw_spin_lock_irq(&lock->wait_lock); |
1824 | /* | 1826 | /* |
1827 | * Do an unconditional try-lock, this deals with the lock stealing | ||
1828 | * state where __rt_mutex_futex_unlock() -> mark_wakeup_next_waiter() | ||
1829 | * sets a NULL owner. | ||
1830 | * | ||
1831 | * We're not interested in the return value, because the subsequent | ||
1832 | * test on rt_mutex_owner() will infer that. If the trylock succeeded, | ||
1833 | * we will own the lock and it will have removed the waiter. If we | ||
1834 | * failed the trylock, we're still not owner and we need to remove | ||
1835 | * ourselves. | ||
1836 | */ | ||
1837 | try_to_take_rt_mutex(lock, current, waiter); | ||
1838 | /* | ||
1825 | * Unless we're the owner; we're still enqueued on the wait_list. | 1839 | * Unless we're the owner; we're still enqueued on the wait_list. |
1826 | * So check if we became owner, if not, take us off the wait_list. | 1840 | * So check if we became owner, if not, take us off the wait_list. |
1827 | */ | 1841 | */ |
1828 | if (rt_mutex_owner(lock) != current) { | 1842 | if (rt_mutex_owner(lock) != current) { |
1829 | remove_waiter(lock, waiter); | 1843 | remove_waiter(lock, waiter); |
1830 | fixup_rt_mutex_waiters(lock); | ||
1831 | cleanup = true; | 1844 | cleanup = true; |
1832 | } | 1845 | } |
1833 | |||
1834 | /* | 1846 | /* |
1835 | * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might | 1847 | * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might |
1836 | * have to fix that up. | 1848 | * have to fix that up. |