From: Jakub Bogusz Date: Thu, 9 Jul 2020 22:57:23 +0000 (-0700) Subject: libbpf: Fix libbpf hashmap on (I)LP32 architectures X-Git-Tag: v5.10.7~2151^2~3^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b2f9f1535bb93ee5fa2ea30ac1c26fa0d676154c;p=platform%2Fkernel%2Flinux-rpi.git libbpf: Fix libbpf hashmap on (I)LP32 architectures 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 Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20200709225723.1069937-1-andriin@fb.com --- diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h index df59fd4fc95b..e0af36b0e5d8 100644 --- a/tools/lib/bpf/hashmap.h +++ b/tools/lib/bpf/hashmap.h @@ -11,14 +11,18 @@ #include #include #include -#ifndef __WORDSIZE -#define __WORDSIZE (__SIZEOF_LONG__ * 8) -#endif 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);