diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index b766d28accd6..3184d3b9cadf 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -1781,13 +1781,14 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, | |||
1781 | * | 1781 | * |
1782 | * The basic logical guarantee of a futex is that it blocks ONLY | 1782 | * The basic logical guarantee of a futex is that it blocks ONLY |
1783 | * if cond(var) is known to be true at the time of blocking, for | 1783 | * if cond(var) is known to be true at the time of blocking, for |
1784 | * any cond. If we queued after testing *uaddr, that would open | 1784 | * any cond. If we locked the hash-bucket after testing *uaddr, that |
1785 | * a race condition where we could block indefinitely with | 1785 | * would open a race condition where we could block indefinitely with |
1786 | * cond(var) false, which would violate the guarantee. | 1786 | * cond(var) false, which would violate the guarantee. |
1787 | * | 1787 | * |
1788 | * A consequence is that futex_wait() can return zero and absorb | 1788 | * On the other hand, we insert q and release the hash-bucket only |
1789 | * a wakeup when *uaddr != val on entry to the syscall. This is | 1789 | * after testing *uaddr. This guarantees that futex_wait() will NOT |
1790 | * rare, but normal. | 1790 | * absorb a wakeup if *uaddr does not match the desired values |
1791 | * while the syscall executes. | ||
1791 | */ | 1792 | */ |
1792 | retry: | 1793 | retry: |
1793 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); | 1794 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); |