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 9 struct { 10 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 11 __uint(key_size, sizeof(__u32)); 12 __uint(value_size, sizeof(int)); 13 __uint(map_flags, BPF_F_PRESERVE_ELEMS); 14 } events SEC(".maps"); 15 16 reading_map prev_readings SEC(".maps"); 17 reading_map diff_readings SEC(".maps"); 18 19 SEC("raw_tp/sched_switch") 20 int BPF_PROG(on_switch) 21 { 22 struct bpf_perf_event_value val, *prev_val, *diff_val; 23 __u32 key = bpf_get_smp_processor_id(); 24 __u32 zero = 0; 25 long err; 26 27 prev_val = bpf_map_lookup_elem(&prev_readings, &zero); 28 if (!prev_val) 29 return 0; 30 31 diff_val = bpf_map_lookup_elem(&diff_readings, &zero); 32 if (!diff_val) 33 return 0; 34 35 err = bpf_perf_event_read_value(&events, key, &val, sizeof(val)); 36 if (err) 37 return 0; 38 39 diff_val->counter = val.counter - prev_val->counter; 40 diff_val->enabled = val.enabled - prev_val->enabled; 41 diff_val->running = val.running - prev_val->running; 42 *prev_val = val; 43 return 0; 44 } 45 46 char LICENSE[] SEC("license") = "Dual BSD/GPL"; 47