summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Dugue <sebastien.dugue@bull.net>2006-06-27 02:55:03 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 17:32:48 -0700
commit59e0e0ace7d33e8c0c125042f153f80fcc56b39e (patch)
treee73a795bd99b39a886fe3f9b46f85dbf53db5316
parent95e02ca9bb5324360e7dea1ea1c563036d84a5e6 (diff)
[PATCH] futex_requeue() optimization
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>
-rw-r--r--kernel/futex.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index b305b7f8dad..6c91f938005 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -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;
}
}