I am implementing bpftrace's histogram in libbpf.
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u64);
__type(value, u64);
} latency_map SEC(".maps");
u64 bin = log2(latency);
void *read = bpf_map_lookup_elem(&indent_map, &bin);
u64 count = (read) ? (*(u64*)(read) + 1) : 1;
bpf_map_update_elem(&latency_map, &bin, &count, BPF_ANY);
This is Map: LatencyGroup -> Frequency
Now I want to make this a keyed histogram Map: String -> LatencyGroup -> Frequency
, as in
@ns[comm] = hist(nsecs - @start[tid]); delete(@start[tid]);
BPF_MAP_TYPE_HASH_OF_MAPS
seems a good fit for this but I am stuck at this.
struct InnerLatencyMap {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u64); // bin
__type(value, u64); // count
};
struct {
__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
__uint(max_entries, 1024);
__type(key, struct Key);
__array(values, struct InnerLatencyMap);
//_array(values, struct InnerLatencyMap);
} latency_map SEC(".maps");
void increment(struct Key key, u64 bin) {
void *read = bpf_map_lookup_elem(&latency_map, &key);
struct bpf_map* inner_latency_map;
if (read) {
inner_latency_map = (struct bpf_map*)read;
read = bpf_map_lookup_elem(inner_latency_map, &bin);
u64 count = (read) ? (*(u64*)read + 1) : 1;
bpf_map_update_elem(inner_latency_map, &bin, &count, BPF_ANY);
} else {
struct bpf_map* inner_latency_map = bpf_map_create(
BPF_MAP_TYPE_HASH,
NULL,
sizeof(struct Key),
sizeof(u64),
512,
NULL,
);
bpf_map_update_elem(&latency_map, &function_key, inner_latency_map, BPF_NOEXIST);
u64 count = 1;
bpf_map_update_elem(&inner_latency_map, &bin, &count, BPF_NOEXIST);
}
}
libbpf-rs couldn't find bpf_map_create
but #include <bpf/bpf.h>
causes the compile error.
#include "vmlinux.h"
#include <bpf/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/usdt.bpf.h>
In file included from src/bpf/python.bpf.c:5:
In file included from /tmp/.tmpHfkjYT/bpf/src/bpf/bpf.h:26:
In file included from /usr/include/linux/bpf.h:11:
In file included from /usr/include/linux/types.h:9:
/usr/include/linux/posix_types.h:27:3: error: typedef redefinition with different types ('struct __kernel_fd_set' vs 'struct __kernel_fd_set')
} __kernel_fd_set;
^
src/bpf/vmlinux.h:41117:3: note: previous definition is here
} __kernel_fd_set;
^
In file included from src/bpf/python.bpf.c:5:
In file included from /tmp/.tmpHfkjYT/bpf/src/bpf/bpf.h:26:
In file included from /usr/include/linux/bpf.h:11:
In file included from /usr/include/linux/types.h:9:
In file included from /usr/include/linux/posix_types.h:36:
In file included from /usr/include/asm/posix_types.h:7:
In file included from /usr/include/asm/posix_types_64.h:18:
/usr/include/asm-generic/posix_types.h:68:22: error: typedef redefinition with different types ('unsigned int' vs '__kernel_ulong_t' (aka 'unsigned long'))
typedef unsigned int __kernel_size_t;
^
src/bpf/vmlinux.h:434:26: note: previous definition is here
typedef __kernel_ulong_t __kernel_size_t;
^
In file included from src/bpf/python.bpf.c:5:
In file included from /tmp/.tmpHfkjYT/bpf/src/bpf/bpf.h:26:
In file included from /usr/include/linux/bpf.h:11:
In file included from /usr/include/linux/types.h:9:
In file included from /usr/include/linux/posix_types.h:36:
In file included from /usr/include/asm/posix_types.h:7:
In file included from /usr/include/asm/posix_types_64.h:18:
/usr/include/asm-generic/posix_types.h:69:14: error: typedef redefinition with different types ('int' vs '__kernel_long_t' (aka 'long'))
...
How can I use BPF_MAP_TYPE_HASH_OF_MAPS?
bfptrace does not use BPF_MAP_TYPE_HASH_OF_MAPS. Instead appends 8 bytes of a bucket number to each key.
to read it, bpftrace iterates them one by one, extract 'a' from 'a00', 'a01', and so on.
ref:
BPFtrace::print_map_hist