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