aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 3717e7b306e0..19eb089ca003 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
716 struct futex_pi_state **ps, 716 struct futex_pi_state **ps,
717 struct task_struct *task, int set_waiters) 717 struct task_struct *task, int set_waiters)
718{ 718{
719 int lock_taken, ret, ownerdied = 0; 719 int lock_taken, ret, force_take = 0;
720 u32 uval, newval, curval, vpid = task_pid_vnr(task); 720 u32 uval, newval, curval, vpid = task_pid_vnr(task);
721 721
722retry: 722retry:
@@ -755,17 +755,15 @@ retry:
755 newval = curval | FUTEX_WAITERS; 755 newval = curval | FUTEX_WAITERS;
756 756
757 /* 757 /*
758 * There are two cases, where a futex might have no owner (the 758 * Should we force take the futex? See below.
759 * owner TID is 0): OWNER_DIED. We take over the futex in this
760 * case. We also do an unconditional take over, when the owner
761 * of the futex died.
762 *
763 * This is safe as we are protected by the hash bucket lock !
764 */ 759 */
765 if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { 760 if (unlikely(force_take)) {
766 /* Keep the OWNER_DIED bit */ 761 /*
762 * Keep the OWNER_DIED and the WAITERS bit and set the
763 * new TID value.
764 */
767 newval = (curval & ~FUTEX_TID_MASK) | vpid; 765 newval = (curval & ~FUTEX_TID_MASK) | vpid;
768 ownerdied = 0; 766 force_take = 0;
769 lock_taken = 1; 767 lock_taken = 1;
770 } 768 }
771 769
@@ -775,7 +773,7 @@ retry:
775 goto retry; 773 goto retry;
776 774
777 /* 775 /*
778 * We took the lock due to owner died take over. 776 * We took the lock due to forced take over.
779 */ 777 */
780 if (unlikely(lock_taken)) 778 if (unlikely(lock_taken))
781 return 1; 779 return 1;
@@ -790,20 +788,25 @@ retry:
790 switch (ret) { 788 switch (ret) {
791 case -ESRCH: 789 case -ESRCH:
792 /* 790 /*
793 * No owner found for this futex. Check if the 791 * We failed to find an owner for this
794 * OWNER_DIED bit is set to figure out whether 792 * futex. So we have no pi_state to block
795 * this is a robust futex or not. 793 * on. This can happen in two cases:
794 *
795 * 1) The owner died
796 * 2) A stale FUTEX_WAITERS bit
797 *
798 * Re-read the futex value.
796 */ 799 */
797 if (get_futex_value_locked(&curval, uaddr)) 800 if (get_futex_value_locked(&curval, uaddr))
798 return -EFAULT; 801 return -EFAULT;
799 802
800 /* 803 /*
801 * We simply start over in case of a robust 804 * If the owner died or we have a stale
802 * futex. The code above will take the futex 805 * WAITERS bit the owner TID in the user space
803 * and return happy. 806 * futex is 0.
804 */ 807 */
805 if (curval & FUTEX_OWNER_DIED) { 808 if (!(curval & FUTEX_TID_MASK)) {
806 ownerdied = 1; 809 force_take = 1;
807 goto retry; 810 goto retry;
808 } 811 }
809 default: 812 default:
@@ -840,6 +843,9 @@ static void wake_futex(struct futex_q *q)
840{ 843{
841 struct task_struct *p = q->task; 844 struct task_struct *p = q->task;
842 845
846 if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n"))
847 return;
848
843 /* 849 /*
844 * We set q->lock_ptr = NULL _before_ we wake up the task. If 850 * We set q->lock_ptr = NULL _before_ we wake up the task. If
845 * a non-futex wake up happens on another CPU then the task 851 * a non-futex wake up happens on another CPU then the task
@@ -1075,6 +1081,10 @@ retry_private:
1075 1081
1076 plist_for_each_entry_safe(this, next, head, list) { 1082 plist_for_each_entry_safe(this, next, head, list) {
1077 if (match_futex (&this->key, &key1)) { 1083 if (match_futex (&this->key, &key1)) {
1084 if (this->pi_state || this->rt_waiter) {
1085 ret = -EINVAL;
1086 goto out_unlock;
1087 }
1078 wake_futex(this); 1088 wake_futex(this);
1079 if (++ret >= nr_wake) 1089 if (++ret >= nr_wake)
1080 break; 1090 break;
@@ -1087,6 +1097,10 @@ retry_private:
1087 op_ret = 0; 1097 op_ret = 0;
1088 plist_for_each_entry_safe(this, next, head, list) { 1098 plist_for_each_entry_safe(this, next, head, list) {
1089 if (match_futex (&this->key, &key2)) { 1099 if (match_futex (&this->key, &key2)) {
1100 if (this->pi_state || this->rt_waiter) {
1101 ret = -EINVAL;
1102 goto out_unlock;
1103 }
1090 wake_futex(this); 1104 wake_futex(this);
1091 if (++op_ret >= nr_wake2) 1105 if (++op_ret >= nr_wake2)
1092 break; 1106 break;
@@ -1095,6 +1109,7 @@ retry_private:
1095 ret += op_ret; 1109 ret += op_ret;
1096 } 1110 }
1097 1111
1112out_unlock:
1098 double_unlock_hb(hb1, hb2); 1113 double_unlock_hb(hb1, hb2);
1099out_put_keys: 1114out_put_keys:
1100 put_futex_key(&key2); 1115 put_futex_key(&key2);
@@ -1384,9 +1399,13 @@ retry_private:
1384 /* 1399 /*
1385 * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always 1400 * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
1386 * be paired with each other and no other futex ops. 1401 * be paired with each other and no other futex ops.
1402 *
1403 * We should never be requeueing a futex_q with a pi_state,
1404 * which is awaiting a futex_unlock_pi().
1387 */ 1405 */
1388 if ((requeue_pi && !this->rt_waiter) || 1406 if ((requeue_pi && !this->rt_waiter) ||
1389 (!requeue_pi && this->rt_waiter)) { 1407 (!requeue_pi && this->rt_waiter) ||
1408 this->pi_state) {
1390 ret = -EINVAL; 1409 ret = -EINVAL;
1391 break; 1410 break;
1392 } 1411 }