diff options
| author | Darren Hart <dvhltc@us.ibm.com> | 2008-12-29 18:49:53 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-12-30 00:38:15 -0500 |
| commit | 42d35d48ce7cefb9429880af19d1c329d1554e7a (patch) | |
| tree | a8c73b7ffd1e481e3b5152e3142c9feb5f7464a1 | |
| parent | b56863630ddbdea6e22df8835f78f0b1da037103 (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.c | 67 |
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); |
| 726 | out: | ||
| 727 | put_futex_key(fshared, &key); | 726 | put_futex_key(fshared, &key); |
| 727 | out: | ||
| 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); |
| 830 | out: | 830 | out_put_keys: |
| 831 | put_futex_key(fshared, &key2); | 831 | put_futex_key(fshared, &key2); |
| 832 | out_put_key1: | ||
| 832 | put_futex_key(fshared, &key1); | 833 | put_futex_key(fshared, &key1); |
| 833 | 834 | out: | |
| 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: | 851 | retry: |
| 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 | ||
| 923 | out: | 924 | out_put_keys: |
| 924 | put_futex_key(fshared, &key2); | 925 | put_futex_key(fshared, &key2); |
| 926 | out_put_key1: | ||
| 925 | put_futex_key(fshared, &key1); | 927 | put_futex_key(fshared, &key1); |
| 928 | out: | ||
| 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: | 989 | retry: |
| 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: | 1171 | retry: |
| 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: | 1305 | out_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 | |||
| 1309 | out: | ||
| 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: | 1358 | retry: |
| 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: | 1364 | retry_unlocked: |
| 1361 | hb = queue_lock(&q); | 1365 | hb = queue_lock(&q); |
| 1362 | 1366 | ||
| 1363 | retry_locked: | 1367 | retry_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: | 1561 | out_unlock_put_key: |
| 1558 | queue_unlock(&q, hb); | 1562 | queue_unlock(&q, hb); |
| 1559 | 1563 | ||
| 1560 | out_release_sem: | 1564 | out_put_key: |
| 1561 | put_futex_key(fshared, &q.key); | 1565 | put_futex_key(fshared, &q.key); |
| 1566 | out: | ||
| 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: | 1571 | uaddr_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 | ||
| 1669 | out_unlock: | 1674 | out_unlock: |
| 1670 | spin_unlock(&hb->lock); | 1675 | spin_unlock(&hb->lock); |
| 1671 | out: | ||
| 1672 | put_futex_key(fshared, &key); | 1676 | put_futex_key(fshared, &key); |
| 1673 | 1677 | ||
| 1678 | out: | ||
| 1674 | return ret; | 1679 | return ret; |
| 1675 | 1680 | ||
| 1676 | pi_faulted: | 1681 | pi_faulted: |
