futex: Use futex_top_waiter() in lookup_pi_state()
authorThomas Gleixner <tglx@linutronix.de>
Wed, 11 Jun 2014 20:45:39 +0000 (20:45 +0000)
committerThomas Gleixner <tglx@linutronix.de>
Sat, 21 Jun 2014 20:26:23 +0000 (22:26 +0200)
No point in open coding the same function again.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Darren Hart <darren@dvhart.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Davidlohr Bueso <davidlohr@hp.com>
Cc: Kees Cook <kees@outflux.net>
Cc: wad@chromium.org
Link: http://lkml.kernel.org/r/20140611204237.092947239@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/futex.c

index 346d5c28054518739040a9b604da1821420d606e..fff1ed9b1c4375089399a9acaaf95e048d022252 100644 (file)
@@ -796,87 +796,85 @@ static int
 lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
                union futex_key *key, struct futex_pi_state **ps)
 {
+       struct futex_q *match = futex_top_waiter(hb, key);
        struct futex_pi_state *pi_state = NULL;
-       struct futex_q *this, *next;
        struct task_struct *p;
        pid_t pid = uval & FUTEX_TID_MASK;
 
-       plist_for_each_entry_safe(this, next, &hb->chain, list) {
-               if (match_futex(&this->key, key)) {
-                       /*
-                        * Sanity check the waiter before increasing
-                        * the refcount and attaching to it.
-                        */
-                       pi_state = this->pi_state;
-                       /*
-                        * Userspace might have messed up non-PI and
-                        * PI futexes [3]
-                        */
-                       if (unlikely(!pi_state))
-                               return -EINVAL;
+       if (match) {
+               /*
+                * Sanity check the waiter before increasing the
+                * refcount and attaching to it.
+                */
+               pi_state = match->pi_state;
+               /*
+                * Userspace might have messed up non-PI and PI
+                * futexes [3]
+                */
+               if (unlikely(!pi_state))
+                       return -EINVAL;
 
-                       WARN_ON(!atomic_read(&pi_state->refcount));
+               WARN_ON(!atomic_read(&pi_state->refcount));
 
+               /*
+                * Handle the owner died case:
+                */
+               if (uval & FUTEX_OWNER_DIED) {
                        /*
-                        * Handle the owner died case:
+                        * exit_pi_state_list sets owner to NULL and
+                        * wakes the topmost waiter. The task which
+                        * acquires the pi_state->rt_mutex will fixup
+                        * owner.
                         */
-                       if (uval & FUTEX_OWNER_DIED) {
+                       if (!pi_state->owner) {
                                /*
-                                * exit_pi_state_list sets owner to NULL and
-                                * wakes the topmost waiter. The task which
-                                * acquires the pi_state->rt_mutex will fixup
-                                * owner.
+                                * No pi state owner, but the user
+                                * space TID is not 0. Inconsistent
+                                * state. [5]
                                 */
-                               if (!pi_state->owner) {
-                                       /*
-                                        * No pi state owner, but the user
-                                        * space TID is not 0. Inconsistent
-                                        * state. [5]
-                                        */
-                                       if (pid)
-                                               return -EINVAL;
-                                       /*
-                                        * Take a ref on the state and
-                                        * return. [4]
-                                        */
-                                       goto out_state;
-                               }
-
-                               /*
-                                * If TID is 0, then either the dying owner
-                                * has not yet executed exit_pi_state_list()
-                                * or some waiter acquired the rtmutex in the
-                                * pi state, but did not yet fixup the TID in
-                                * user space.
-                                *
-                                * Take a ref on the state and return. [6]
-                                */
-                               if (!pid)
-                                       goto out_state;
-                       } else {
+                               if (pid)
+                                       return -EINVAL;
                                /*
-                                * If the owner died bit is not set,
-                                * then the pi_state must have an
-                                * owner. [7]
+                                * Take a ref on the state and
+                                * return. [4]
                                 */
-                               if (!pi_state->owner)
-                                       return -EINVAL;
+                               goto out_state;
                        }
 
                        /*
-                        * Bail out if user space manipulated the
-                        * futex value. If pi state exists then the
-                        * owner TID must be the same as the user
-                        * space TID. [9/10]
+                        * If TID is 0, then either the dying owner
+                        * has not yet executed exit_pi_state_list()
+                        * or some waiter acquired the rtmutex in the
+                        * pi state, but did not yet fixup the TID in
+                        * user space.
+                        *
+                        * Take a ref on the state and return. [6]
+                        */
+                       if (!pid)
+                               goto out_state;
+               } else {
+                       /*
+                        * If the owner died bit is not set,
+                        * then the pi_state must have an
+                        * owner. [7]
                         */
-                       if (pid != task_pid_vnr(pi_state->owner))
+                       if (!pi_state->owner)
                                return -EINVAL;
-
-               out_state:
-                       atomic_inc(&pi_state->refcount);
-                       *ps = pi_state;
-                       return 0;
                }
+
+               /*
+                * Bail out if user space manipulated the
+                * futex value. If pi state exists then the
+                * owner TID must be the same as the user
+                * space TID. [9/10]
+                */
+               if (pid != task_pid_vnr(pi_state->owner))
+                       return -EINVAL;
+
+       out_state:
+               atomic_inc(&pi_state->refcount);
+               *ps = pi_state;
+               return 0;
        }
 
        /*