[PATCH] futex_requeue() optimization
authorSebastien Dugue <sebastien.dugue@bull.net>
Tue, 27 Jun 2006 09:55:03 +0000 (02:55 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 28 Jun 2006 00:32:48 +0000 (17:32 -0700)
In futex_requeue(), when the 2 futexes keys hash to the same bucket, there
is no need to move the futex_q to the end of the bucket list.

Signed-off-by: Sebastien Dugue <sebastien.dugue@bull.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/futex.c

index b305b7f..6c91f93 100644 (file)
@@ -827,17 +827,20 @@ static int futex_requeue(u32 __user *uaddr1, u32 __user *uaddr2,
                if (++ret <= nr_wake) {
                        wake_futex(this);
                } else {
-                       list_move_tail(&this->list, &hb2->chain);
-                       this->lock_ptr = &hb2->lock;
+                       /*
+                        * If key1 and key2 hash to the same bucket, no need to
+                        * requeue.
+                        */
+                       if (likely(head1 != &hb2->chain)) {
+                               list_move_tail(&this->list, &hb2->chain);
+                               this->lock_ptr = &hb2->lock;
+                       }
                        this->key = key2;
                        get_key_refs(&key2);
                        drop_count++;
 
                        if (ret - nr_wake >= nr_requeue)
                                break;
-                       /* Make sure to stop if key1 == key2: */
-                       if (head1 == &hb2->chain && head1 != &next->list)
-                               head1 = &this->list;
                }
        }