// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) // Copyright (c) 2021 Facebook #include "vmlinux.h" #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h> #include "bperf_u.h" struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(key_size, sizeof(__u32)); __uint(value_size, sizeof(struct bpf_perf_event_value)); __uint(max_entries, 1); } diff_readings SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(key_size, sizeof(__u32)); __uint(value_size, sizeof(struct bpf_perf_event_value)); __uint(max_entries, 1); } accum_readings SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(key_size, sizeof(__u32)); __uint(value_size, sizeof(__u32)); } filter SEC(".maps"); enum bperf_filter_type type = 0; int enabled = 0; SEC("fexit/XXX") int BPF_PROG(fexit_XXX) { struct bpf_perf_event_value *diff_val, *accum_val; __u32 filter_key, zero = 0; __u32 *accum_key; if (!enabled) return 0; switch (type) { case BPERF_FILTER_GLOBAL: accum_key = &zero; goto do_add; case BPERF_FILTER_CPU: filter_key = bpf_get_smp_processor_id(); break; case BPERF_FILTER_PID: filter_key = bpf_get_current_pid_tgid() & 0xffffffff; break; case BPERF_FILTER_TGID: filter_key = bpf_get_current_pid_tgid() >> 32; break; default: return 0; } accum_key = bpf_map_lookup_elem(&filter, &filter_key); if (!accum_key) return 0; do_add: diff_val = bpf_map_lookup_elem(&diff_readings, &zero); if (!diff_val) return 0; accum_val = bpf_map_lookup_elem(&accum_readings, accum_key); if (!accum_val) return 0; accum_val->counter += diff_val->counter; accum_val->enabled += diff_val->enabled; accum_val->running += diff_val->running; return 0; } char LICENSE[] SEC("license") = "Dual BSD/GPL";