18c2ecf20Sopenharmony_ci#include <linux/ptrace.h> 28c2ecf20Sopenharmony_ci#include <linux/version.h> 38c2ecf20Sopenharmony_ci#include <uapi/linux/bpf.h> 48c2ecf20Sopenharmony_ci#include <bpf/bpf_helpers.h> 58c2ecf20Sopenharmony_ci#include <bpf/bpf_tracing.h> 68c2ecf20Sopenharmony_ci#include <bpf/bpf_core_read.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_cistruct { 98c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 108c2ecf20Sopenharmony_ci __uint(key_size, sizeof(int)); 118c2ecf20Sopenharmony_ci __uint(value_size, sizeof(u32)); 128c2ecf20Sopenharmony_ci __uint(max_entries, 64); 138c2ecf20Sopenharmony_ci} counters SEC(".maps"); 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistruct { 168c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 178c2ecf20Sopenharmony_ci __type(key, int); 188c2ecf20Sopenharmony_ci __type(value, u64); 198c2ecf20Sopenharmony_ci __uint(max_entries, 64); 208c2ecf20Sopenharmony_ci} values SEC(".maps"); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct { 238c2ecf20Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 248c2ecf20Sopenharmony_ci __type(key, int); 258c2ecf20Sopenharmony_ci __type(value, struct bpf_perf_event_value); 268c2ecf20Sopenharmony_ci __uint(max_entries, 64); 278c2ecf20Sopenharmony_ci} values2 SEC(".maps"); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ciSEC("kprobe/htab_map_get_next_key") 308c2ecf20Sopenharmony_ciint bpf_prog1(struct pt_regs *ctx) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci u32 key = bpf_get_smp_processor_id(); 338c2ecf20Sopenharmony_ci u64 count, *val; 348c2ecf20Sopenharmony_ci s64 error; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci count = bpf_perf_event_read(&counters, key); 378c2ecf20Sopenharmony_ci error = (s64)count; 388c2ecf20Sopenharmony_ci if (error <= -2 && error >= -22) 398c2ecf20Sopenharmony_ci return 0; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci val = bpf_map_lookup_elem(&values, &key); 428c2ecf20Sopenharmony_ci if (val) 438c2ecf20Sopenharmony_ci *val = count; 448c2ecf20Sopenharmony_ci else 458c2ecf20Sopenharmony_ci bpf_map_update_elem(&values, &key, &count, BPF_NOEXIST); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci return 0; 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* 518c2ecf20Sopenharmony_ci * Since *_map_lookup_elem can't be expected to trigger bpf programs 528c2ecf20Sopenharmony_ci * due to potential deadlocks (bpf_disable_instrumentation), this bpf 538c2ecf20Sopenharmony_ci * program will be attached to bpf_map_copy_value (which is called 548c2ecf20Sopenharmony_ci * from map_lookup_elem) and will only filter the hashtable type. 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_ciSEC("kprobe/bpf_map_copy_value") 578c2ecf20Sopenharmony_ciint BPF_KPROBE(bpf_prog2, struct bpf_map *map) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci u32 key = bpf_get_smp_processor_id(); 608c2ecf20Sopenharmony_ci struct bpf_perf_event_value *val, buf; 618c2ecf20Sopenharmony_ci enum bpf_map_type type; 628c2ecf20Sopenharmony_ci int error; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci type = BPF_CORE_READ(map, map_type); 658c2ecf20Sopenharmony_ci if (type != BPF_MAP_TYPE_HASH) 668c2ecf20Sopenharmony_ci return 0; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf)); 698c2ecf20Sopenharmony_ci if (error) 708c2ecf20Sopenharmony_ci return 0; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci val = bpf_map_lookup_elem(&values2, &key); 738c2ecf20Sopenharmony_ci if (val) 748c2ecf20Sopenharmony_ci *val = buf; 758c2ecf20Sopenharmony_ci else 768c2ecf20Sopenharmony_ci bpf_map_update_elem(&values2, &key, &buf, BPF_NOEXIST); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci return 0; 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cichar _license[] SEC("license") = "GPL"; 828c2ecf20Sopenharmony_ciu32 _version SEC("version") = LINUX_VERSION_CODE; 83