]> git.pld-linux.org Git - packages/kernel-tools.git/blobdiff - kernel-tools-bpf-hashmap.patch
- added bpf-upstream patch with upstream bpf/hashmap.h changes and rewritten hashmap...
[packages/kernel-tools.git] / kernel-tools-bpf-hashmap.patch
index e5300b1f96dac17f2eb0176a8ce2ac9120d36a72..18334beb52665585fbf460fa6df842a9011e3b0d 100644 (file)
@@ -1,24 +1,32 @@
-Fix broken hashmap implementation to ensure that hash_bits returns value fitting in
-given bits (for bits > 0): multiplier is long long, so shift bits must be based on
-long long, not __WORDSIZE.
+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.
+
 --- linux-5.7/tools/lib/bpf/hashmap.h.orig     2020-06-01 01:49:15.000000000 +0200
 +++ linux-5.7/tools/lib/bpf/hashmap.h  2020-06-21 15:22:07.298466419 +0200
-@@ -10,17 +10,12 @@
+@@ -11,14 +11,18 @@
  #include <stdbool.h>
  #include <stddef.h>
--#ifdef __GLIBC__
--#include <bits/wordsize.h>
--#else
--#include <bits/reg.h>
+ #include <limits.h>
+-#ifndef __WORDSIZE
+-#define __WORDSIZE (__SIZEOF_LONG__ * 8)
 -#endif
- #include "libbpf_internal.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);
This page took 0.088721 seconds and 4 git commands to generate.