0001
0002
0003 #include "vmlinux.h"
0004 #include <bpf/bpf_helpers.h>
0005 #include <bpf/bpf_tracing.h>
0006 #include "bperf_u.h"
0007
0008 struct {
0009 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
0010 __uint(key_size, sizeof(__u32));
0011 __uint(value_size, sizeof(struct bpf_perf_event_value));
0012 __uint(max_entries, 1);
0013 } diff_readings SEC(".maps");
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 } accum_readings SEC(".maps");
0021
0022 struct {
0023 __uint(type, BPF_MAP_TYPE_HASH);
0024 __uint(key_size, sizeof(__u32));
0025 __uint(value_size, sizeof(__u32));
0026 } filter SEC(".maps");
0027
0028 enum bperf_filter_type type = 0;
0029 int enabled = 0;
0030
0031 SEC("fexit/XXX")
0032 int BPF_PROG(fexit_XXX)
0033 {
0034 struct bpf_perf_event_value *diff_val, *accum_val;
0035 __u32 filter_key, zero = 0;
0036 __u32 *accum_key;
0037
0038 if (!enabled)
0039 return 0;
0040
0041 switch (type) {
0042 case BPERF_FILTER_GLOBAL:
0043 accum_key = &zero;
0044 goto do_add;
0045 case BPERF_FILTER_CPU:
0046 filter_key = bpf_get_smp_processor_id();
0047 break;
0048 case BPERF_FILTER_PID:
0049 filter_key = bpf_get_current_pid_tgid() & 0xffffffff;
0050 break;
0051 case BPERF_FILTER_TGID:
0052 filter_key = bpf_get_current_pid_tgid() >> 32;
0053 break;
0054 default:
0055 return 0;
0056 }
0057
0058 accum_key = bpf_map_lookup_elem(&filter, &filter_key);
0059 if (!accum_key)
0060 return 0;
0061
0062 do_add:
0063 diff_val = bpf_map_lookup_elem(&diff_readings, &zero);
0064 if (!diff_val)
0065 return 0;
0066
0067 accum_val = bpf_map_lookup_elem(&accum_readings, accum_key);
0068 if (!accum_val)
0069 return 0;
0070
0071 accum_val->counter += diff_val->counter;
0072 accum_val->enabled += diff_val->enabled;
0073 accum_val->running += diff_val->running;
0074
0075 return 0;
0076 }
0077
0078 char LICENSE[] SEC("license") = "Dual BSD/GPL";