1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
5 #include "bpf_arena_alloc.h"
6 #include "bpf_arena_list.h"
9 struct arena_list_head head
;
11 typedef struct htab_bucket __arena htab_bucket_t
;
14 htab_bucket_t
*buckets
;
17 typedef struct htab __arena htab_t
;
19 static inline htab_bucket_t
*__select_bucket(htab_t
*htab
, __u32 hash
)
21 htab_bucket_t
*b
= htab
->buckets
;
24 return &b
[hash
& (htab
->n_buckets
- 1)];
27 static inline arena_list_head_t
*select_bucket(htab_t
*htab
, __u32 hash
)
29 return &__select_bucket(htab
, hash
)->head
;
36 struct arena_list_node hash_node
;
38 typedef struct hashtab_elem __arena hashtab_elem_t
;
40 static hashtab_elem_t
*lookup_elem_raw(arena_list_head_t
*head
, __u32 hash
, int key
)
44 list_for_each_entry(l
, head
, hash_node
)
45 if (l
->hash
== hash
&& l
->key
== key
)
51 static int htab_hash(int key
)
56 __weak
int htab_lookup_elem(htab_t
*htab __arg_arena
, int key
)
58 hashtab_elem_t
*l_old
;
59 arena_list_head_t
*head
;
62 head
= select_bucket(htab
, key
);
63 l_old
= lookup_elem_raw(head
, htab_hash(key
), key
);
69 __weak
int htab_update_elem(htab_t
*htab __arg_arena
, int key
, int value
)
71 hashtab_elem_t
*l_new
= NULL
, *l_old
;
72 arena_list_head_t
*head
;
75 head
= select_bucket(htab
, key
);
76 l_old
= lookup_elem_raw(head
, htab_hash(key
), key
);
78 l_new
= bpf_alloc(sizeof(*l_new
));
82 l_new
->hash
= htab_hash(key
);
85 list_add_head(&l_new
->hash_node
, head
);
87 list_del(&l_old
->hash_node
);
93 void htab_init(htab_t
*htab
)
95 void __arena
*buckets
= bpf_arena_alloc_pages(&arena
, NULL
, 2, NUMA_NO_NODE
, 0);
98 htab
->buckets
= buckets
;
99 htab
->n_buckets
= 2 * PAGE_SIZE
/ sizeof(struct htab_bucket
);