82 lines · c
1#include "vmlinux.h"2#include <linux/version.h>3#include <bpf/bpf_helpers.h>4#include <bpf/bpf_tracing.h>5#include <bpf/bpf_core_read.h>6 7struct {8 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);9 __uint(key_size, sizeof(int));10 __uint(value_size, sizeof(u32));11 __uint(max_entries, 64);12} counters SEC(".maps");13 14struct {15 __uint(type, BPF_MAP_TYPE_HASH);16 __type(key, int);17 __type(value, u64);18 __uint(max_entries, 64);19} values SEC(".maps");20 21struct {22 __uint(type, BPF_MAP_TYPE_HASH);23 __type(key, int);24 __type(value, struct bpf_perf_event_value);25 __uint(max_entries, 64);26} values2 SEC(".maps");27 28SEC("kprobe/htab_map_get_next_key")29int bpf_prog1(struct pt_regs *ctx)30{31 u32 key = bpf_get_smp_processor_id();32 u64 count, *val;33 s64 error;34 35 count = bpf_perf_event_read(&counters, key);36 error = (s64)count;37 if (error <= -2 && error >= -22)38 return 0;39 40 val = bpf_map_lookup_elem(&values, &key);41 if (val)42 *val = count;43 else44 bpf_map_update_elem(&values, &key, &count, BPF_NOEXIST);45 46 return 0;47}48 49/*50 * Since *_map_lookup_elem can't be expected to trigger bpf programs51 * due to potential deadlocks (bpf_disable_instrumentation), this bpf52 * program will be attached to bpf_map_copy_value (which is called53 * from map_lookup_elem) and will only filter the hashtable type.54 */55SEC("kprobe/bpf_map_copy_value")56int BPF_KPROBE(bpf_prog2, struct bpf_map *map)57{58 u32 key = bpf_get_smp_processor_id();59 struct bpf_perf_event_value *val, buf;60 enum bpf_map_type type;61 int error;62 63 type = BPF_CORE_READ(map, map_type);64 if (type != BPF_MAP_TYPE_HASH)65 return 0;66 67 error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf));68 if (error)69 return 0;70 71 val = bpf_map_lookup_elem(&values2, &key);72 if (val)73 *val = buf;74 else75 bpf_map_update_elem(&values2, &key, &buf, BPF_NOEXIST);76 77 return 0;78}79 80char _license[] SEC("license") = "GPL";81u32 _version SEC("version") = LINUX_VERSION_CODE;82