Commit b2f9f153 authored by Jakub Bogusz's avatar Jakub Bogusz Committed by Alexei Starovoitov

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: e3b92422 ("libbpf: add resizable non-thread safe internal hashmap")
Signed-off-by: default avatarJakub Bogusz <qboosh@pld-linux.org>
Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200709225723.1069937-1-andriin@fb.com
parent f43cb0d6
...@@ -11,14 +11,18 @@ ...@@ -11,14 +11,18 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <limits.h> #include <limits.h>
#ifndef __WORDSIZE
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
#endif
static inline size_t hash_bits(size_t h, int bits) static inline size_t hash_bits(size_t h, int bits)
{ {
/* shuffle bits and return requested number of upper 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); typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment