diff --git a/src/ebpf/lib/cuckoo_filter.h b/src/ebpf/lib/cuckoo_filter.h index 9e2692b..174af42 100644 --- a/src/ebpf/lib/cuckoo_filter.h +++ b/src/ebpf/lib/cuckoo_filter.h @@ -79,6 +79,17 @@ typedef enum { #define CUCKOO_MAX_KICK_ATTEMPTS 10 #endif +#ifndef bpf_clamp_uminmax +#define bpf_clamp_uminmax(VAR, UMIN, UMAX) \ + asm volatile("if %0 >= %[min] goto +2\n" \ + "%0 = %[min]\n" \ + "goto +2\n" \ + "if %0 <= %[max] goto +1\n" \ + "%0 = %[max]\n" \ + : "+r"(VAR) \ + : [min] "i"(UMIN), [max] "i"(UMAX)) +#endif + #define BPF_CUCKOO_FILTER(_name, _key_type, _max_entries) \ \ typedef struct _name##_cuckoo_filter_cell_s { \ @@ -160,7 +171,7 @@ typedef enum { fingerprint &= _name##_cuckoo_filter_cfg.MASK; \ fingerprint += !fingerprint; \ \ - volatile uint32_t h2 = \ + uint32_t h2 = \ ((h1 ^ hash(&fingerprint, sizeof(fingerprint), _name##_cuckoo_filter_cfg.BUCKET_COUNT, \ 900, _name##_cuckoo_filter_cfg.HASH_SEED)) % \ _name##_cuckoo_filter_cfg.BUCKET_COUNT); \ @@ -182,7 +193,7 @@ typedef enum { size_t ii; \ for (ii = 0; ii < _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET; ++ii) { \ uint32_t idx = (h1 * _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET) + ii; \ - idx = idx % CUCKOO_MAX_BUCKET_COUNT; \ + bpf_clamp_uminmax(idx, 0, CUCKOO_MAX_BUCKET_COUNT - 1); \ uint16_t elem = filter->buckets[idx].fingerprint; \ if (elem == fingerprint) { \ result->was_found = true; \ @@ -190,7 +201,7 @@ typedef enum { } \ \ idx = (h2 * _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET) + ii; \ - idx = idx % (CUCKOO_MAX_BUCKET_COUNT); \ + bpf_clamp_uminmax(idx, 0, CUCKOO_MAX_BUCKET_COUNT - 1); \ elem = filter->buckets[idx].fingerprint; \ if (elem == fingerprint) { \ result->was_found = true; \ @@ -212,7 +223,7 @@ typedef enum { \ for (ii = 0; ii < _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET; ++ii) { \ uint32_t idx = (h * _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET) + ii; \ - idx = idx % CUCKOO_MAX_BUCKET_COUNT; \ + bpf_clamp_uminmax(idx, 0, CUCKOO_MAX_BUCKET_COUNT - 1); \ \ _name##_cuckoo_filter_cell_t *nest = &filter->buckets[idx]; \ if (0 == nest->fingerprint) { \ @@ -230,7 +241,7 @@ typedef enum { \ for (ii = 0; ii < _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET; ++ii) { \ uint32_t idx = (h * _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET) + ii; \ - idx = idx % CUCKOO_MAX_BUCKET_COUNT; \ + bpf_clamp_uminmax(idx, 0, CUCKOO_MAX_BUCKET_COUNT - 1); \ \ _name##_cuckoo_filter_cell_t *nest = &filter->buckets[idx]; \ if (fp == nest->fingerprint) { \ @@ -286,10 +297,7 @@ typedef enum { (bpf_get_prandom_u32() % _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET); \ uint32_t idx = (row * _name##_cuckoo_filter_cfg.CUCKOO_NESTS_PER_BUCKET) + col; \ \ - if (idx < 0 || idx >= CUCKOO_MAX_BUCKET_COUNT) { \ - return CUCKOO_FILTER_ALLOCATION_FAILED; \ - } \ - idx = idx % CUCKOO_MAX_BUCKET_COUNT; \ + bpf_clamp_uminmax(idx, 0, CUCKOO_MAX_BUCKET_COUNT - 1); \ \ size_t elem = loop_ctx.map->buckets[idx].fingerprint; \ loop_ctx.map->buckets[idx].fingerprint = loop_ctx.fingerprint; \