0001
0002
0003 #include "vmlinux.h"
0004 #include <bpf/bpf_helpers.h>
0005 #include <bpf/bpf_tracing.h>
0006
0007
0008 struct {
0009 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
0010 __uint(key_size, sizeof(__u32));
0011 __uint(value_size, sizeof(int));
0012 } events SEC(".maps");
0013
0014
0015 struct {
0016 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
0017 __uint(key_size, sizeof(__u32));
0018 __uint(value_size, sizeof(struct bpf_perf_event_value));
0019 __uint(max_entries, 1);
0020 } fentry_readings SEC(".maps");
0021
0022
0023 struct {
0024 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
0025 __uint(key_size, sizeof(__u32));
0026 __uint(value_size, sizeof(struct bpf_perf_event_value));
0027 __uint(max_entries, 1);
0028 } accum_readings SEC(".maps");
0029
0030 const volatile __u32 num_cpu = 1;
0031
0032 SEC("fentry/XXX")
0033 int BPF_PROG(fentry_XXX)
0034 {
0035 __u32 key = bpf_get_smp_processor_id();
0036 struct bpf_perf_event_value *ptr;
0037 __u32 zero = 0;
0038 long err;
0039
0040
0041 ptr = bpf_map_lookup_elem(&fentry_readings, &zero);
0042 if (!ptr)
0043 return 0;
0044
0045 err = bpf_perf_event_read_value(&events, key, ptr, sizeof(*ptr));
0046 if (err)
0047 return 0;
0048
0049 return 0;
0050 }
0051
0052 static inline void
0053 fexit_update_maps(struct bpf_perf_event_value *after)
0054 {
0055 struct bpf_perf_event_value *before, diff;
0056 __u32 zero = 0;
0057
0058 before = bpf_map_lookup_elem(&fentry_readings, &zero);
0059
0060 if (before && before->counter) {
0061 struct bpf_perf_event_value *accum;
0062
0063 diff.counter = after->counter - before->counter;
0064 diff.enabled = after->enabled - before->enabled;
0065 diff.running = after->running - before->running;
0066
0067 accum = bpf_map_lookup_elem(&accum_readings, &zero);
0068 if (accum) {
0069 accum->counter += diff.counter;
0070 accum->enabled += diff.enabled;
0071 accum->running += diff.running;
0072 }
0073 }
0074 }
0075
0076 SEC("fexit/XXX")
0077 int BPF_PROG(fexit_XXX)
0078 {
0079 struct bpf_perf_event_value reading;
0080 __u32 cpu = bpf_get_smp_processor_id();
0081 int err;
0082
0083
0084 err = bpf_perf_event_read_value(&events, cpu, &reading, sizeof(reading));
0085 if (err)
0086 return 0;
0087
0088 fexit_update_maps(&reading);
0089 return 0;
0090 }
0091
0092 char LICENSE[] SEC("license") = "Dual BSD/GPL";