aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2020-03-08 19:07:17 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-04-28 19:03:52 +0100
commitb74665947b7399bd222346e2d33afd51810d0444 (patch)
tree9f9e89f45262aa4b9e4b9ff9295887ecbcaa3eb3
parent87903c4d3a9b422cd1d254b693e84b95f9df0706 (diff)
downloadlinux-stable-b74665947b7399bd222346e2d33afd51810d0444.tar.gz
futex: Unbreak futex hashing
commit 8d67743653dce5a0e7aa500fcccb237cde7ad88e upstream. The recent futex inode life time fix changed the ordering of the futex key union struct members, but forgot to adjust the hash function accordingly, As a result the hashing omits the leading 64bit and even hashes beyond the futex key causing a bad hash distribution which led to a ~100% performance regression. Hand in the futex key pointer instead of a random struct member and make the size calculation based of the struct offset. Fixes: 8019ad13ef7f ("futex: Fix inode life-time issue") Reported-by: Rong Chen <rong.a.chen@intel.com> Decoded-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Rong Chen <rong.a.chen@intel.com> Link: https://lkml.kernel.org/r/87h7yy90ve.fsf@nanos.tec.linutronix.de Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Cc: Jann Horn <jannh@google.com>
-rw-r--r--kernel/futex.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 80d5b82196853..4efd512b062dc 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -309,9 +309,9 @@ static inline int hb_waiters_pending(struct futex_hash_bucket *hb)
*/
static struct futex_hash_bucket *hash_futex(union futex_key *key)
{
- u32 hash = jhash2((u32*)&key->both.word,
- (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
+ u32 hash = jhash2((u32 *)key, offsetof(typeof(*key), both.offset) / 4,
key->both.offset);
+
return &futex_queues[hash & (futex_hashsize - 1)];
}