[PATCH] fs/xattr: use jhash for simple_xattr hashing

From: Christian Brauner

Date: Thu May 28 2026 - 04:23:26 EST


After commit c81b88b8932b ("simpe_xattr: use per-sb cache") switched
sx_hashfn() from jhash() to xxh32(), arm64 allnoconfig fails to link:

ld: fs/xattr.o: in function `simple_xattr_obj_hashfn':
xattr.c:(.text+0x2f0): undefined reference to `xxh32'
ld: fs/xattr.o: in function `simple_xattr_hashfn':
xattr.c:(.text+0x340): undefined reference to `xxh32'
ld: fs/xattr.o: in function `simple_xattr_get':
xattr.c:(.text+0x2374): undefined reference to `xxh32'

xxh32() lives in lib/xxhash.c, which is only built when CONFIG_XXHASH
is selected. fs/xattr.o is built unconditionally via fs/Makefile's
obj-y, so a caller from fs/xattr.c needs XXHASH wired in too.

The obvious fix is to add a hidden always-y config in fs/Kconfig that
selects XXHASH. But that is the wrong fix for this code: xxh32()
does not actually buy simple_xattr anything over jhash() at these
key sizes.

xxh32's throughput advantage comes from a four-lane multiply-add main
loop that processes 16 bytes per iteration, designed for the
checksum- and compression-sized payloads xxhash was written for (lz4,
zstd, btrfs csum, ksm page dedup). The fixed setup cost of priming
those four lanes only amortizes once the input is well past one
iteration. The keys hashed in sx_hashfn() are tiny - 8 bytes for the
parent list_head pointer and ~10-30 bytes for typical xattr names
like "user.foo" or "security.evm" - exactly the size regime where
jhash equals or beats xxh32. Both pass SMHasher and have equivalent
avalanche properties, so the rhashtable's collision rate is
unchanged.

Switch sx_hashfn() back to jhash(). It is header-inline, has the
same distribution quality on these inputs, matches the hash used by
the original rhashtable-based infrastructure in commit b32c4a213698
("xattr: add rhashtable-based simple_xattr infrastructure"), and
avoids dragging lib/xxhash.o into every kernel build for a two-call
hash composer that does not benefit from xxh32's bulk-hashing
strengths.

Reported-by: Mark Brown <broonie@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/ahRHShZFjI8AsT8G@xxxxxxxxxxxxx
Fixes: c81b88b8932b ("simpe_xattr: use per-sb cache")
Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
fs/xattr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 31cae48e11a4..4416033af881 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -23,7 +23,7 @@
#include <linux/vmalloc.h>
#include <linux/posix_acl_xattr.h>
#include <linux/rhashtable.h>
-#include <linux/xxhash.h>
+#include <linux/jhash.h>

#include <linux/uaccess.h>

@@ -1277,7 +1277,7 @@ struct simple_xattr *simple_xattr_alloc(const void *value, size_t size)

static u32 sx_hashfn(const char *name, const struct list_head *parent, u32 seed)
{
- return xxh32(name, strlen(name), xxh32(&parent, sizeof(parent), seed));
+ return jhash(name, strlen(name), jhash(&parent, sizeof(parent), seed));
}

static u32 simple_xattr_hashfn(const void *data, u32 len, u32 seed)
--
2.47.3


--53uwv4bsz3i44rlq--