aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Hart <dvhltc@us.ibm.com>2008-12-29 18:49:53 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-30 00:38:15 -0500
commit42d35d48ce7cefb9429880af19d1c329d1554e7a (patch)
treea8c73b7ffd1e481e3b5152e3142c9feb5f7464a1
parentb56863630ddbdea6e22df8835f78f0b1da037103 (diff)
futex: make futex_(get|put)_key() calls symmetric
Impact: cleanup This patch makes the calls to futex_get_key_refs() and futex_drop_key_refs() explicitly symmetric by only "putting" keys we successfully "got". Also cleanup a couple return points that didn't "put" after a successful "get". Build and boot tested on an x86_64 system. Signed-off-by: Darren Hart <dvhltc@us.ibm.com> Cc: <stable@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--kernel/futex.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index b4f87bac91c1..c5ac55cc0c16 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -723,8 +723,8 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)
723 } 723 }
724 724
725 spin_unlock(&hb->lock); 725 spin_unlock(&hb->lock);
726out:
727 put_futex_key(fshared, &key); 726 put_futex_key(fshared, &key);
727out:
728 return ret; 728 return ret;
729} 729}
730 730
@@ -748,7 +748,7 @@ retryfull:
748 goto out; 748 goto out;
749 ret = get_futex_key(uaddr2, fshared, &key2); 749 ret = get_futex_key(uaddr2, fshared, &key2);
750 if (unlikely(ret != 0)) 750 if (unlikely(ret != 0))
751 goto out; 751 goto out_put_key1;
752 752
753 hb1 = hash_futex(&key1); 753 hb1 = hash_futex(&key1);
754 hb2 = hash_futex(&key2); 754 hb2 = hash_futex(&key2);
@@ -770,12 +770,12 @@ retry:
770 * but we might get them from range checking 770 * but we might get them from range checking
771 */ 771 */
772 ret = op_ret; 772 ret = op_ret;
773 goto out; 773 goto out_put_keys;
774#endif 774#endif
775 775
776 if (unlikely(op_ret != -EFAULT)) { 776 if (unlikely(op_ret != -EFAULT)) {
777 ret = op_ret; 777 ret = op_ret;
778 goto out; 778 goto out_put_keys;
779 } 779 }
780 780
781 /* 781 /*
@@ -789,7 +789,7 @@ retry:
789 ret = futex_handle_fault((unsigned long)uaddr2, 789 ret = futex_handle_fault((unsigned long)uaddr2,
790 attempt); 790 attempt);
791 if (ret) 791 if (ret)
792 goto out; 792 goto out_put_keys;
793 goto retry; 793 goto retry;
794 } 794 }
795 795
@@ -827,10 +827,11 @@ retry:
827 spin_unlock(&hb1->lock); 827 spin_unlock(&hb1->lock);
828 if (hb1 != hb2) 828 if (hb1 != hb2)
829 spin_unlock(&hb2->lock); 829 spin_unlock(&hb2->lock);
830out: 830out_put_keys:
831 put_futex_key(fshared, &key2); 831 put_futex_key(fshared, &key2);
832out_put_key1:
832 put_futex_key(fshared, &key1); 833 put_futex_key(fshared, &key1);
833 834out:
834 return ret; 835 return ret;
835} 836}
836 837
@@ -847,13 +848,13 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
847 struct futex_q *this, *next; 848 struct futex_q *this, *next;
848 int ret, drop_count = 0; 849 int ret, drop_count = 0;
849 850
850 retry: 851retry:
851 ret = get_futex_key(uaddr1, fshared, &key1); 852 ret = get_futex_key(uaddr1, fshared, &key1);
852 if (unlikely(ret != 0)) 853 if (unlikely(ret != 0))
853 goto out; 854 goto out;
854 ret = get_futex_key(uaddr2, fshared, &key2); 855 ret = get_futex_key(uaddr2, fshared, &key2);
855 if (unlikely(ret != 0)) 856 if (unlikely(ret != 0))
856 goto out; 857 goto out_put_key1;
857 858
858 hb1 = hash_futex(&key1); 859 hb1 = hash_futex(&key1);
859 hb2 = hash_futex(&key2); 860 hb2 = hash_futex(&key2);
@@ -875,7 +876,7 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
875 if (!ret) 876 if (!ret)
876 goto retry; 877 goto retry;
877 878
878 return ret; 879 goto out_put_keys;
879 } 880 }
880 if (curval != *cmpval) { 881 if (curval != *cmpval) {
881 ret = -EAGAIN; 882 ret = -EAGAIN;
@@ -920,9 +921,11 @@ out_unlock:
920 while (--drop_count >= 0) 921 while (--drop_count >= 0)
921 drop_futex_key_refs(&key1); 922 drop_futex_key_refs(&key1);
922 923
923out: 924out_put_keys:
924 put_futex_key(fshared, &key2); 925 put_futex_key(fshared, &key2);
926out_put_key1:
925 put_futex_key(fshared, &key1); 927 put_futex_key(fshared, &key1);
928out:
926 return ret; 929 return ret;
927} 930}
928 931
@@ -983,7 +986,7 @@ static int unqueue_me(struct futex_q *q)
983 int ret = 0; 986 int ret = 0;
984 987
985 /* In the common case we don't take the spinlock, which is nice. */ 988 /* In the common case we don't take the spinlock, which is nice. */
986 retry: 989retry:
987 lock_ptr = q->lock_ptr; 990 lock_ptr = q->lock_ptr;
988 barrier(); 991 barrier();
989 if (lock_ptr != NULL) { 992 if (lock_ptr != NULL) {
@@ -1165,11 +1168,11 @@ static int futex_wait(u32 __user *uaddr, int fshared,
1165 1168
1166 q.pi_state = NULL; 1169 q.pi_state = NULL;
1167 q.bitset = bitset; 1170 q.bitset = bitset;
1168 retry: 1171retry:
1169 q.key = FUTEX_KEY_INIT; 1172 q.key = FUTEX_KEY_INIT;
1170 ret = get_futex_key(uaddr, fshared, &q.key); 1173 ret = get_futex_key(uaddr, fshared, &q.key);
1171 if (unlikely(ret != 0)) 1174 if (unlikely(ret != 0))
1172 goto out_release_sem; 1175 goto out;
1173 1176
1174 hb = queue_lock(&q); 1177 hb = queue_lock(&q);
1175 1178
@@ -1197,6 +1200,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
1197 1200
1198 if (unlikely(ret)) { 1201 if (unlikely(ret)) {
1199 queue_unlock(&q, hb); 1202 queue_unlock(&q, hb);
1203 put_futex_key(fshared, &q.key);
1200 1204
1201 ret = get_user(uval, uaddr); 1205 ret = get_user(uval, uaddr);
1202 1206
@@ -1206,7 +1210,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
1206 } 1210 }
1207 ret = -EWOULDBLOCK; 1211 ret = -EWOULDBLOCK;
1208 if (uval != val) 1212 if (uval != val)
1209 goto out_unlock_release_sem; 1213 goto out_unlock_put_key;
1210 1214
1211 /* Only actually queue if *uaddr contained val. */ 1215 /* Only actually queue if *uaddr contained val. */
1212 queue_me(&q, hb); 1216 queue_me(&q, hb);
@@ -1298,11 +1302,11 @@ static int futex_wait(u32 __user *uaddr, int fshared,
1298 return -ERESTART_RESTARTBLOCK; 1302 return -ERESTART_RESTARTBLOCK;
1299 } 1303 }
1300 1304
1301 out_unlock_release_sem: 1305out_unlock_put_key:
1302 queue_unlock(&q, hb); 1306 queue_unlock(&q, hb);
1303
1304 out_release_sem:
1305 put_futex_key(fshared, &q.key); 1307 put_futex_key(fshared, &q.key);
1308
1309out:
1306 return ret; 1310 return ret;
1307} 1311}
1308 1312
@@ -1351,16 +1355,16 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1351 } 1355 }
1352 1356
1353 q.pi_state = NULL; 1357 q.pi_state = NULL;
1354 retry: 1358retry:
1355 q.key = FUTEX_KEY_INIT; 1359 q.key = FUTEX_KEY_INIT;
1356 ret = get_futex_key(uaddr, fshared, &q.key); 1360 ret = get_futex_key(uaddr, fshared, &q.key);
1357 if (unlikely(ret != 0)) 1361 if (unlikely(ret != 0))
1358 goto out_release_sem; 1362 goto out;
1359 1363
1360 retry_unlocked: 1364retry_unlocked:
1361 hb = queue_lock(&q); 1365 hb = queue_lock(&q);
1362 1366
1363 retry_locked: 1367retry_locked:
1364 ret = lock_taken = 0; 1368 ret = lock_taken = 0;
1365 1369
1366 /* 1370 /*
@@ -1381,14 +1385,14 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1381 */ 1385 */
1382 if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) { 1386 if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) {
1383 ret = -EDEADLK; 1387 ret = -EDEADLK;
1384 goto out_unlock_release_sem; 1388 goto out_unlock_put_key;
1385 } 1389 }
1386 1390
1387 /* 1391 /*
1388 * Surprise - we got the lock. Just return to userspace: 1392 * Surprise - we got the lock. Just return to userspace:
1389 */ 1393 */
1390 if (unlikely(!curval)) 1394 if (unlikely(!curval))
1391 goto out_unlock_release_sem; 1395 goto out_unlock_put_key;
1392 1396
1393 uval = curval; 1397 uval = curval;
1394 1398
@@ -1424,7 +1428,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1424 * We took the lock due to owner died take over. 1428 * We took the lock due to owner died take over.
1425 */ 1429 */
1426 if (unlikely(lock_taken)) 1430 if (unlikely(lock_taken))
1427 goto out_unlock_release_sem; 1431 goto out_unlock_put_key;
1428 1432
1429 /* 1433 /*
1430 * We dont have the lock. Look up the PI state (or create it if 1434 * We dont have the lock. Look up the PI state (or create it if
@@ -1463,7 +1467,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1463 goto retry_locked; 1467 goto retry_locked;
1464 } 1468 }
1465 default: 1469 default:
1466 goto out_unlock_release_sem; 1470 goto out_unlock_put_key;
1467 } 1471 }
1468 } 1472 }
1469 1473
@@ -1554,16 +1558,17 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1554 destroy_hrtimer_on_stack(&to->timer); 1558 destroy_hrtimer_on_stack(&to->timer);
1555 return ret != -EINTR ? ret : -ERESTARTNOINTR; 1559 return ret != -EINTR ? ret : -ERESTARTNOINTR;
1556 1560
1557 out_unlock_release_sem: 1561out_unlock_put_key:
1558 queue_unlock(&q, hb); 1562 queue_unlock(&q, hb);
1559 1563
1560 out_release_sem: 1564out_put_key:
1561 put_futex_key(fshared, &q.key); 1565 put_futex_key(fshared, &q.key);
1566out:
1562 if (to) 1567 if (to)
1563 destroy_hrtimer_on_stack(&to->timer); 1568 destroy_hrtimer_on_stack(&to->timer);
1564 return ret; 1569 return ret;
1565 1570
1566 uaddr_faulted: 1571uaddr_faulted:
1567 /* 1572 /*
1568 * We have to r/w *(int __user *)uaddr, and we have to modify it 1573 * We have to r/w *(int __user *)uaddr, and we have to modify it
1569 * atomically. Therefore, if we continue to fault after get_user() 1574 * atomically. Therefore, if we continue to fault after get_user()
@@ -1576,7 +1581,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1576 if (attempt++) { 1581 if (attempt++) {
1577 ret = futex_handle_fault((unsigned long)uaddr, attempt); 1582 ret = futex_handle_fault((unsigned long)uaddr, attempt);
1578 if (ret) 1583 if (ret)
1579 goto out_release_sem; 1584 goto out_put_key;
1580 goto retry_unlocked; 1585 goto retry_unlocked;
1581 } 1586 }
1582 1587
@@ -1668,9 +1673,9 @@ retry_unlocked:
1668 1673
1669out_unlock: 1674out_unlock:
1670 spin_unlock(&hb->lock); 1675 spin_unlock(&hb->lock);
1671out:
1672 put_futex_key(fshared, &key); 1676 put_futex_key(fshared, &key);
1673 1677
1678out:
1674 return ret; 1679 return ret;
1675 1680
1676pi_faulted: 1681pi_faulted: