1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 // Copyright (c) 2021 Facebook 3 #include <linux/bpf.h> 4 #include <linux/perf_event.h> 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_tracing.h> 7 #include "bperf.h" 8 #include "bperf_u.h" 9 10 reading_map diff_readings SEC(".maps"); 11 reading_map accum_readings SEC(".maps"); 12 13 struct { 14 __uint(type, BPF_MAP_TYPE_HASH); 15 __uint(key_size, sizeof(__u32)); 16 __uint(value_size, sizeof(__u32)); 17 } filter SEC(".maps"); 18 19 enum bperf_filter_type type = 0; 20 int enabled = 0; 21 22 SEC("fexit/XXX") 23 int BPF_PROG(fexit_XXX) 24 { 25 struct bpf_perf_event_value *diff_val, *accum_val; 26 __u32 filter_key, zero = 0; 27 __u32 *accum_key; 28 29 if (!enabled) 30 return 0; 31 32 switch (type) { 33 case BPERF_FILTER_GLOBAL: 34 accum_key = &zero; 35 goto do_add; 36 case BPERF_FILTER_CPU: 37 filter_key = bpf_get_smp_processor_id(); 38 break; 39 case BPERF_FILTER_PID: 40 filter_key = bpf_get_current_pid_tgid() & 0xffffffff; 41 break; 42 case BPERF_FILTER_TGID: 43 filter_key = bpf_get_current_pid_tgid() >> 32; 44 break; 45 default: 46 return 0; 47 } 48 49 accum_key = bpf_map_lookup_elem(&filter, &filter_key); 50 if (!accum_key) 51 return 0; 52 53 do_add: 54 diff_val = bpf_map_lookup_elem(&diff_readings, &zero); 55 if (!diff_val) 56 return 0; 57 58 accum_val = bpf_map_lookup_elem(&accum_readings, accum_key); 59 if (!accum_val) 60 return 0; 61 62 accum_val->counter += diff_val->counter; 63 accum_val->enabled += diff_val->enabled; 64 accum_val->running += diff_val->running; 65 66 return 0; 67 } 68 69 char LICENSE[] SEC("license") = "Dual BSD/GPL"; 70