SHA256
1
0
forked from pool/dwarves
dwarves/libbpf-Fix-libbpf-hashmap-on-I-LP32-architectures.patch

46 lines
1.6 KiB
Diff

From: Jakub Bogusz <qboosh@pld-linux.org>
Date: Thu, 9 Jul 2020 15:57:23 -0700
Subject: libbpf: Fix libbpf hashmap on (I)LP32 architectures
Git-commit: b2f9f1535bb93ee5fa2ea30ac1c26fa0d676154c
Patch-mainline: 5.8-rc5
References: x86_32 crashes fix
On ILP32, 64-bit result was shifted by value calculated for 32-bit long type
and returned value was much outside hashmap capacity.
As advised by Andrii Nakryiko, this patch uses different hashing variant for
architectures with size_t shorter than long long.
Fixes: e3b924224028 ("libbpf: add resizable non-thread safe internal hashmap")
Signed-off-by: Jakub Bogusz <qboosh@pld-linux.org>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200709225723.1069937-1-andriin@fb.com
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
lib/bpf/src/hashmap.h | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/lib/bpf/src/hashmap.h
+++ b/lib/bpf/src/hashmap.h
@@ -16,11 +16,19 @@
#include <bits/reg.h>
#endif
#include "libbpf_internal.h"
+#include <limits.h>
static inline size_t hash_bits(size_t h, int bits)
{
/* shuffle bits and return requested number of upper bits */
- return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
+#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
+ /* LP64 case */
+ return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
+#elif (__SIZEOF_SIZE_T__ <= __SIZEOF_LONG__)
+ return (h * 2654435769lu) >> (__SIZEOF_LONG__ * 8 - bits);
+#else
+# error "Unsupported size_t size"
+#endif
}
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);