diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index be3bff2315ff..a0514e01c3eb 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -1452,11 +1452,7 @@ static void mark_wake_futex(struct wake_q_head *wake_q, struct futex_q *q) | |||
1452 | if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) | 1452 | if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) |
1453 | return; | 1453 | return; |
1454 | 1454 | ||
1455 | /* | 1455 | get_task_struct(p); |
1456 | * Queue the task for later wakeup for after we've released | ||
1457 | * the hb->lock. wake_q_add() grabs reference to p. | ||
1458 | */ | ||
1459 | wake_q_add(wake_q, p); | ||
1460 | __unqueue_futex(q); | 1456 | __unqueue_futex(q); |
1461 | /* | 1457 | /* |
1462 | * The waiting task can free the futex_q as soon as q->lock_ptr = NULL | 1458 | * The waiting task can free the futex_q as soon as q->lock_ptr = NULL |
@@ -1466,6 +1462,13 @@ static void mark_wake_futex(struct wake_q_head *wake_q, struct futex_q *q) | |||
1466 | * plist_del in __unqueue_futex(). | 1462 | * plist_del in __unqueue_futex(). |
1467 | */ | 1463 | */ |
1468 | smp_store_release(&q->lock_ptr, NULL); | 1464 | smp_store_release(&q->lock_ptr, NULL); |
1465 | |||
1466 | /* | ||
1467 | * Queue the task for later wakeup for after we've released | ||
1468 | * the hb->lock. wake_q_add() grabs reference to p. | ||
1469 | */ | ||
1470 | wake_q_add(wake_q, p); | ||
1471 | put_task_struct(p); | ||
1469 | } | 1472 | } |
1470 | 1473 | ||
1471 | /* | 1474 | /* |
@@ -2218,11 +2221,11 @@ static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) | |||
2218 | * decrement the counter at queue_unlock() when some error has | 2221 | * decrement the counter at queue_unlock() when some error has |
2219 | * occurred and we don't end up adding the task to the list. | 2222 | * occurred and we don't end up adding the task to the list. |
2220 | */ | 2223 | */ |
2221 | hb_waiters_inc(hb); | 2224 | hb_waiters_inc(hb); /* implies smp_mb(); (A) */ |
2222 | 2225 | ||
2223 | q->lock_ptr = &hb->lock; | 2226 | q->lock_ptr = &hb->lock; |
2224 | 2227 | ||
2225 | spin_lock(&hb->lock); /* implies smp_mb(); (A) */ | 2228 | spin_lock(&hb->lock); |
2226 | return hb; | 2229 | return hb; |
2227 | } | 2230 | } |
2228 | 2231 | ||
@@ -2858,35 +2861,39 @@ retry_private: | |||
2858 | * and BUG when futex_unlock_pi() interleaves with this. | 2861 | * and BUG when futex_unlock_pi() interleaves with this. |
2859 | * | 2862 | * |
2860 | * Therefore acquire wait_lock while holding hb->lock, but drop the | 2863 | * Therefore acquire wait_lock while holding hb->lock, but drop the |
2861 | * latter before calling rt_mutex_start_proxy_lock(). This still fully | 2864 | * latter before calling __rt_mutex_start_proxy_lock(). This |
2862 | * serializes against futex_unlock_pi() as that does the exact same | 2865 | * interleaves with futex_unlock_pi() -- which does a similar lock |
2863 | * lock handoff sequence. | 2866 | * handoff -- such that the latter can observe the futex_q::pi_state |
2867 | * before __rt_mutex_start_proxy_lock() is done. | ||
2864 | */ | 2868 | */ |
2865 | raw_spin_lock_irq(&q.pi_state->pi_mutex.wait_lock); | 2869 | raw_spin_lock_irq(&q.pi_state->pi_mutex.wait_lock); |
2866 | spin_unlock(q.lock_ptr); | 2870 | spin_unlock(q.lock_ptr); |
2871 | /* | ||
2872 | * __rt_mutex_start_proxy_lock() unconditionally enqueues the @rt_waiter | ||
2873 | * such that futex_unlock_pi() is guaranteed to observe the waiter when | ||
2874 | * it sees the futex_q::pi_state. | ||
2875 | */ | ||
2867 | ret = __rt_mutex_start_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter, current); | 2876 | ret = __rt_mutex_start_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter, current); |
2868 | raw_spin_unlock_irq(&q.pi_state->pi_mutex.wait_lock); | 2877 | raw_spin_unlock_irq(&q.pi_state->pi_mutex.wait_lock); |
2869 | 2878 | ||
2870 | if (ret) { | 2879 | if (ret) { |
2871 | if (ret == 1) | 2880 | if (ret == 1) |
2872 | ret = 0; | 2881 | ret = 0; |
2873 | 2882 | goto cleanup; | |
2874 | spin_lock(q.lock_ptr); | ||
2875 | goto no_block; | ||
2876 | } | 2883 | } |
2877 | 2884 | ||
2878 | |||
2879 | if (unlikely(to)) | 2885 | if (unlikely(to)) |
2880 | hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); | 2886 | hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); |
2881 | 2887 | ||
2882 | ret = rt_mutex_wait_proxy_lock(&q.pi_state->pi_mutex, to, &rt_waiter); | 2888 | ret = rt_mutex_wait_proxy_lock(&q.pi_state->pi_mutex, to, &rt_waiter); |
2883 | 2889 | ||
2890 | cleanup: | ||
2884 | spin_lock(q.lock_ptr); | 2891 | spin_lock(q.lock_ptr); |
2885 | /* | 2892 | /* |
2886 | * If we failed to acquire the lock (signal/timeout), we must | 2893 | * If we failed to acquire the lock (deadlock/signal/timeout), we must |
2887 | * first acquire the hb->lock before removing the lock from the | 2894 | * first acquire the hb->lock before removing the lock from the |
2888 | * rt_mutex waitqueue, such that we can keep the hb and rt_mutex | 2895 | * rt_mutex waitqueue, such that we can keep the hb and rt_mutex wait |
2889 | * wait lists consistent. | 2896 | * lists consistent. |
2890 | * | 2897 | * |
2891 | * In particular; it is important that futex_unlock_pi() can not | 2898 | * In particular; it is important that futex_unlock_pi() can not |
2892 | * observe this inconsistency. | 2899 | * observe this inconsistency. |
@@ -3010,6 +3017,10 @@ retry: | |||
3010 | * there is no point where we hold neither; and therefore | 3017 | * there is no point where we hold neither; and therefore |
3011 | * wake_futex_pi() must observe a state consistent with what we | 3018 | * wake_futex_pi() must observe a state consistent with what we |
3012 | * observed. | 3019 | * observed. |
3020 | * | ||
3021 | * In particular; this forces __rt_mutex_start_proxy() to | ||
3022 | * complete such that we're guaranteed to observe the | ||
3023 | * rt_waiter. Also see the WARN in wake_futex_pi(). | ||
3013 | */ | 3024 | */ |
3014 | raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); | 3025 | raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); |
3015 | spin_unlock(&hb->lock); | 3026 | spin_unlock(&hb->lock); |