Commit 42d35d48 authored by Darren Hart's avatar Darren Hart Committed by Ingo Molnar
Browse files

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: default avatarDarren Hart <dvhltc@us.ibm.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent b5686363
Loading
Loading
Loading
Loading
+36 −31
Original line number Diff line number Diff line
@@ -723,8 +723,8 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)
	}

	spin_unlock(&hb->lock);
out:
	put_futex_key(fshared, &key);
out:
	return ret;
}

@@ -748,7 +748,7 @@ retryfull:
		goto out;
	ret = get_futex_key(uaddr2, fshared, &key2);
	if (unlikely(ret != 0))
		goto out;
		goto out_put_key1;

	hb1 = hash_futex(&key1);
	hb2 = hash_futex(&key2);
@@ -770,12 +770,12 @@ retry:
		 * but we might get them from range checking
		 */
		ret = op_ret;
		goto out;
		goto out_put_keys;
#endif

		if (unlikely(op_ret != -EFAULT)) {
			ret = op_ret;
			goto out;
			goto out_put_keys;
		}

		/*
@@ -789,7 +789,7 @@ retry:
			ret = futex_handle_fault((unsigned long)uaddr2,
						 attempt);
			if (ret)
				goto out;
				goto out_put_keys;
			goto retry;
		}

@@ -827,10 +827,11 @@ retry:
	spin_unlock(&hb1->lock);
	if (hb1 != hb2)
		spin_unlock(&hb2->lock);
out:
out_put_keys:
	put_futex_key(fshared, &key2);
out_put_key1:
	put_futex_key(fshared, &key1);

out:
	return ret;
}

@@ -853,7 +854,7 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
		goto out;
	ret = get_futex_key(uaddr2, fshared, &key2);
	if (unlikely(ret != 0))
		goto out;
		goto out_put_key1;

	hb1 = hash_futex(&key1);
	hb2 = hash_futex(&key2);
@@ -875,7 +876,7 @@ static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2,
			if (!ret)
				goto retry;

			return ret;
			goto out_put_keys;
		}
		if (curval != *cmpval) {
			ret = -EAGAIN;
@@ -920,9 +921,11 @@ out_unlock:
	while (--drop_count >= 0)
		drop_futex_key_refs(&key1);

out:
out_put_keys:
	put_futex_key(fshared, &key2);
out_put_key1:
	put_futex_key(fshared, &key1);
out:
	return ret;
}

@@ -1169,7 +1172,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
	q.key = FUTEX_KEY_INIT;
	ret = get_futex_key(uaddr, fshared, &q.key);
	if (unlikely(ret != 0))
		goto out_release_sem;
		goto out;

	hb = queue_lock(&q);

@@ -1197,6 +1200,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,

	if (unlikely(ret)) {
		queue_unlock(&q, hb);
		put_futex_key(fshared, &q.key);

		ret = get_user(uval, uaddr);

@@ -1206,7 +1210,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
	}
	ret = -EWOULDBLOCK;
	if (uval != val)
		goto out_unlock_release_sem;
		goto out_unlock_put_key;

	/* Only actually queue if *uaddr contained val.  */
	queue_me(&q, hb);
@@ -1298,11 +1302,11 @@ static int futex_wait(u32 __user *uaddr, int fshared,
		return -ERESTART_RESTARTBLOCK;
	}

 out_unlock_release_sem:
out_unlock_put_key:
	queue_unlock(&q, hb);

 out_release_sem:
	put_futex_key(fshared, &q.key);

out:
	return ret;
}

@@ -1355,7 +1359,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
	q.key = FUTEX_KEY_INIT;
	ret = get_futex_key(uaddr, fshared, &q.key);
	if (unlikely(ret != 0))
		goto out_release_sem;
		goto out;

retry_unlocked:
	hb = queue_lock(&q);
@@ -1381,14 +1385,14 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
	 */
	if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) {
		ret = -EDEADLK;
		goto out_unlock_release_sem;
		goto out_unlock_put_key;
	}

	/*
	 * Surprise - we got the lock. Just return to userspace:
	 */
	if (unlikely(!curval))
		goto out_unlock_release_sem;
		goto out_unlock_put_key;

	uval = curval;

@@ -1424,7 +1428,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
	 * We took the lock due to owner died take over.
	 */
	if (unlikely(lock_taken))
		goto out_unlock_release_sem;
		goto out_unlock_put_key;

	/*
	 * 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,
				goto retry_locked;
			}
		default:
			goto out_unlock_release_sem;
			goto out_unlock_put_key;
		}
	}

@@ -1554,11 +1558,12 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
		destroy_hrtimer_on_stack(&to->timer);
	return ret != -EINTR ? ret : -ERESTARTNOINTR;

 out_unlock_release_sem:
out_unlock_put_key:
	queue_unlock(&q, hb);

 out_release_sem:
out_put_key:
	put_futex_key(fshared, &q.key);
out:
	if (to)
		destroy_hrtimer_on_stack(&to->timer);
	return ret;
@@ -1576,7 +1581,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
	if (attempt++) {
		ret = futex_handle_fault((unsigned long)uaddr, attempt);
		if (ret)
			goto out_release_sem;
			goto out_put_key;
		goto retry_unlocked;
	}

@@ -1668,9 +1673,9 @@ retry_unlocked:

out_unlock:
	spin_unlock(&hb->lock);
out:
	put_futex_key(fshared, &key);

out:
	return ret;

pi_faulted: