mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-25 02:39:39 +08:00
libbpf: Hashmap interface update to allow both long and void* keys/values
An update for libbpf's hashmap interface from void* -> void* to a
polymorphic one, allowing both long and void* keys and values.
This simplifies many use cases in libbpf as hashmaps there are mostly
integer to integer.
Perf copies hashmap implementation from libbpf and has to be
updated as well.
Changes to libbpf, selftests/bpf and perf are packed as a single
commit to avoid compilation issues with any future bisect.
Polymorphic interface is acheived by hiding hashmap interface
functions behind auxiliary macros that take care of necessary
type casts, for example:
#define hashmap_cast_ptr(p) \
({ \
_Static_assert((p) == NULL || sizeof(*(p)) == sizeof(long),\
#p " pointee should be a long-sized integer or a pointer"); \
(long *)(p); \
})
bool hashmap_find(const struct hashmap *map, long key, long *value);
#define hashmap__find(map, key, value) \
hashmap_find((map), (long)(key), hashmap_cast_ptr(value))
- hashmap__find macro casts key and value parameters to long
and long* respectively
- hashmap_cast_ptr ensures that value pointer points to a memory
of appropriate size.
This hack was suggested by Andrii Nakryiko in [1].
This is a follow up for [2].
[1] https://lore.kernel.org/bpf/CAEf4BzZ8KFneEJxFAaNCCFPGqp20hSpS2aCj76uRk3-qZUH5xg@mail.gmail.com/
[2] https://lore.kernel.org/bpf/af1facf9-7bc8-8a3d-0db4-7b3f333589a2@meta.com/T/#m65b28f1d6d969fcd318b556db6a3ad499a42607d
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20221109142611.879983-2-eddyz87@gmail.com
This commit is contained in:
committed by
Andrii Nakryiko
parent
3a387f5a8f
commit
4a65c5d888
28
src/usdt.c
28
src/usdt.c
@@ -873,31 +873,27 @@ static void bpf_link_usdt_dealloc(struct bpf_link *link)
|
||||
free(usdt_link);
|
||||
}
|
||||
|
||||
static size_t specs_hash_fn(const void *key, void *ctx)
|
||||
static size_t specs_hash_fn(long key, void *ctx)
|
||||
{
|
||||
const char *s = key;
|
||||
|
||||
return str_hash(s);
|
||||
return str_hash((char *)key);
|
||||
}
|
||||
|
||||
static bool specs_equal_fn(const void *key1, const void *key2, void *ctx)
|
||||
static bool specs_equal_fn(long key1, long key2, void *ctx)
|
||||
{
|
||||
const char *s1 = key1;
|
||||
const char *s2 = key2;
|
||||
|
||||
return strcmp(s1, s2) == 0;
|
||||
return strcmp((char *)key1, (char *)key2) == 0;
|
||||
}
|
||||
|
||||
static int allocate_spec_id(struct usdt_manager *man, struct hashmap *specs_hash,
|
||||
struct bpf_link_usdt *link, struct usdt_target *target,
|
||||
int *spec_id, bool *is_new)
|
||||
{
|
||||
void *tmp;
|
||||
long tmp;
|
||||
void *new_ids;
|
||||
int err;
|
||||
|
||||
/* check if we already allocated spec ID for this spec string */
|
||||
if (hashmap__find(specs_hash, target->spec_str, &tmp)) {
|
||||
*spec_id = (long)tmp;
|
||||
*spec_id = tmp;
|
||||
*is_new = false;
|
||||
return 0;
|
||||
}
|
||||
@@ -905,17 +901,17 @@ static int allocate_spec_id(struct usdt_manager *man, struct hashmap *specs_hash
|
||||
/* otherwise it's a new ID that needs to be set up in specs map and
|
||||
* returned back to usdt_manager when USDT link is detached
|
||||
*/
|
||||
tmp = libbpf_reallocarray(link->spec_ids, link->spec_cnt + 1, sizeof(*link->spec_ids));
|
||||
if (!tmp)
|
||||
new_ids = libbpf_reallocarray(link->spec_ids, link->spec_cnt + 1, sizeof(*link->spec_ids));
|
||||
if (!new_ids)
|
||||
return -ENOMEM;
|
||||
link->spec_ids = tmp;
|
||||
link->spec_ids = new_ids;
|
||||
|
||||
/* get next free spec ID, giving preference to free list, if not empty */
|
||||
if (man->free_spec_cnt) {
|
||||
*spec_id = man->free_spec_ids[man->free_spec_cnt - 1];
|
||||
|
||||
/* cache spec ID for current spec string for future lookups */
|
||||
err = hashmap__add(specs_hash, target->spec_str, (void *)(long)*spec_id);
|
||||
err = hashmap__add(specs_hash, target->spec_str, *spec_id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -928,7 +924,7 @@ static int allocate_spec_id(struct usdt_manager *man, struct hashmap *specs_hash
|
||||
*spec_id = man->next_free_spec_id;
|
||||
|
||||
/* cache spec ID for current spec string for future lookups */
|
||||
err = hashmap__add(specs_hash, target->spec_str, (void *)(long)*spec_id);
|
||||
err = hashmap__add(specs_hash, target->spec_str, *spec_id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user