return l->data + round_up(key_size, 8);
}
+/* Specialize hash function and objcmp for long sized key */
+static __always_inline int rhtab_key_cmp_long(struct rhashtable_compare_arg *arg,
+ const void *ptr)
+{
+ const unsigned long key1 = *(const unsigned long *)arg->key;
+ const struct rhtab_elem *key2 = ptr;
+
+ return key1 != *(const unsigned long *)key2->data;
+}
+
+static __always_inline u32 rhtab_hashfn_long(const void *data, u32 len, u32 seed)
+{
+ u64 k = *(const unsigned long *)data;
+
+ return (u32)(k ^ (k >> 32)) ^ seed;
+}
+
+static const struct rhashtable_params rhtab_params_long = {
+ .head_offset = offsetof(struct rhtab_elem, node),
+ .key_offset = offsetof(struct rhtab_elem, data),
+ .key_len = sizeof(long),
+ .hashfn = rhtab_hashfn_long,
+ .obj_cmpfn = rhtab_key_cmp_long,
+};
+
static struct bpf_map *rhtab_map_alloc(union bpf_attr *attr)
{
struct rhashtable_params params;
params.nelem_hint = (u32)attr->map_extra;
params.automatic_shrinking = true;
+ if (rhtab->map.key_size == sizeof(long)) {
+ params.hashfn = rhtab_hashfn_long;
+ params.obj_cmpfn = rhtab_key_cmp_long;
+ }
+
err = rhashtable_init(&rhtab->ht, ¶ms);
if (err)
goto free_rhtab;
/* Hold RCU lock in case sleepable program calls via gen_lookup */
guard(rcu)();
+ if (map->key_size == sizeof(long))
+ return rhashtable_lookup_likely(&rhtab->ht, key, rhtab_params_long);
+
return rhashtable_lookup_likely(&rhtab->ht, key, rhtab_params);
}
* raw tracepoints, which we don't have in rhashtable.
*/
bpf_disable_instrumentation();
- err = rhashtable_remove_fast(&rhtab->ht, &elem->node, rhtab_params);
+
+ if (rhtab->map.key_size == sizeof(long))
+ err = rhashtable_remove_fast(&rhtab->ht, &elem->node, rhtab_params_long);
+ else
+ err = rhashtable_remove_fast(&rhtab->ht, &elem->node, rhtab_params);
+
bpf_enable_instrumentation();
if (err)
/* Prevent deadlock for NMI programs attempting to take bucket lock */
bpf_disable_instrumentation();
- tmp = rhashtable_lookup_get_insert_fast(&rhtab->ht, &elem->node, rhtab_params);
+
+ if (map->key_size == sizeof(long))
+ tmp = rhashtable_lookup_get_insert_fast(&rhtab->ht, &elem->node, rhtab_params_long);
+ else
+ tmp = rhashtable_lookup_get_insert_fast(&rhtab->ht, &elem->node, rhtab_params);
+
bpf_enable_instrumentation();
if (tmp) {