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