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
8struct {
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
15struct {
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
22struct {
23	__uint(type, BPF_MAP_TYPE_HASH);
24	__uint(key_size, sizeof(__u32));
25	__uint(value_size, sizeof(__u32));
26} filter SEC(".maps");
27
28enum bperf_filter_type type = 0;
29int enabled = 0;
30
31SEC("fexit/XXX")
32int 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
62do_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
78char LICENSE[] SEC("license") = "Dual BSD/GPL";
79