]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
vfs: dcache: move hashlen_hash() from callers into d_hash()
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jun 2024 18:47:06 +0000 (11:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 19 Jun 2024 19:34:34 +0000 (12:34 -0700)
Both __d_lookup_rcu() and __d_lookup_rcu_op_compare() have the full
'name_hash' value of the qstr that they want to look up, and mask it off
to just the low 32-bit hash before calling down to d_hash().

Other callers just load the 32-bit hash and pass it as the argument.

If we move the masking into d_hash() itself, it simplifies the two
callers that currently do the masking, and is a no-op for the other
cases.  It doesn't actually change the generated code since the compiler
will inline d_hash() and see that the end result is the same.

[ Technically, since the parse tree changes, the code generation may not
  be 100% the same, and for me on x86-64, this does result in gcc
  switching the operands around for one 'cmpl' instruction. So not
  necessarily the exact same code generation, but equivalent ]

However, this does encapsulate the 'd_hash()' operation more, and makes
the shift operation in particular be a "shift 32 bits right, return full
word".  Which matches the instruction semantics on both x86-64 and arm64
better, since a 32-bit shift will clear the upper bits.

That makes the next step of introducing a "shift by runtime constant"
more obvious and generates the shift with no extraneous type masking.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/dcache.c

index 407095188f83a7faeec0a8c0542fb6598952b7be..8b4382f5c99d051104ec9d4b89572d805dd0ad0c 100644 (file)
@@ -100,9 +100,9 @@ static unsigned int d_hash_shift __ro_after_init;
 
 static struct hlist_bl_head *dentry_hashtable __ro_after_init;
 
-static inline struct hlist_bl_head *d_hash(unsigned int hash)
+static inline struct hlist_bl_head *d_hash(unsigned long hashlen)
 {
-       return dentry_hashtable + (hash >> d_hash_shift);
+       return dentry_hashtable + ((u32)hashlen >> d_hash_shift);
 }
 
 #define IN_LOOKUP_SHIFT 10
@@ -2104,7 +2104,7 @@ static noinline struct dentry *__d_lookup_rcu_op_compare(
        unsigned *seqp)
 {
        u64 hashlen = name->hash_len;
-       struct hlist_bl_head *b = d_hash(hashlen_hash(hashlen));
+       struct hlist_bl_head *b = d_hash(hashlen);
        struct hlist_bl_node *node;
        struct dentry *dentry;
 
@@ -2171,7 +2171,7 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent,
 {
        u64 hashlen = name->hash_len;
        const unsigned char *str = name->name;
-       struct hlist_bl_head *b = d_hash(hashlen_hash(hashlen));
+       struct hlist_bl_head *b = d_hash(hashlen);
        struct hlist_bl_node *node;
        struct dentry *dentry;