Path: blob/master/tools/bpf/bpftool/skeleton/profiler.bpf.c
26292 views
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)1// Copyright (c) 2020 Facebook2#include <vmlinux.h>3#include <bpf/bpf_helpers.h>4#include <bpf/bpf_tracing.h>56struct bpf_perf_event_value___local {7__u64 counter;8__u64 enabled;9__u64 running;10} __attribute__((preserve_access_index));1112/* map of perf event fds, num_cpu * num_metric entries */13struct {14__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);15__uint(key_size, sizeof(u32));16__uint(value_size, sizeof(int));17} events SEC(".maps");1819/* readings at fentry */20struct {21__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);22__uint(key_size, sizeof(u32));23__uint(value_size, sizeof(struct bpf_perf_event_value___local));24} fentry_readings SEC(".maps");2526/* accumulated readings */27struct {28__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);29__uint(key_size, sizeof(u32));30__uint(value_size, sizeof(struct bpf_perf_event_value___local));31} accum_readings SEC(".maps");3233/* sample counts, one per cpu */34struct {35__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);36__uint(key_size, sizeof(u32));37__uint(value_size, sizeof(u64));38} counts SEC(".maps");3940const volatile __u32 num_cpu = 1;41const volatile __u32 num_metric = 1;42#define MAX_NUM_METRICS 44344SEC("fentry/XXX")45int BPF_PROG(fentry_XXX)46{47struct bpf_perf_event_value___local *ptrs[MAX_NUM_METRICS];48u32 key = bpf_get_smp_processor_id();49u32 i;5051/* look up before reading, to reduce error */52for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++) {53u32 flag = i;5455ptrs[i] = bpf_map_lookup_elem(&fentry_readings, &flag);56if (!ptrs[i])57return 0;58}5960for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++) {61struct bpf_perf_event_value___local reading;62int err;6364err = bpf_perf_event_read_value(&events, key, (void *)&reading,65sizeof(reading));66if (err)67return 0;68*(ptrs[i]) = reading;69key += num_cpu;70}7172return 0;73}7475static inline void76fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after)77{78struct bpf_perf_event_value___local *before, diff;7980before = bpf_map_lookup_elem(&fentry_readings, &id);81/* only account samples with a valid fentry_reading */82if (before && before->counter) {83struct bpf_perf_event_value___local *accum;8485diff.counter = after->counter - before->counter;86diff.enabled = after->enabled - before->enabled;87diff.running = after->running - before->running;8889accum = bpf_map_lookup_elem(&accum_readings, &id);90if (accum) {91accum->counter += diff.counter;92accum->enabled += diff.enabled;93accum->running += diff.running;94}95}96}9798SEC("fexit/XXX")99int BPF_PROG(fexit_XXX)100{101struct bpf_perf_event_value___local readings[MAX_NUM_METRICS];102u32 cpu = bpf_get_smp_processor_id();103u32 i, zero = 0;104int err;105u64 *count;106107/* read all events before updating the maps, to reduce error */108for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++) {109err = bpf_perf_event_read_value(&events, cpu + i * num_cpu,110(void *)(readings + i),111sizeof(*readings));112if (err)113return 0;114}115count = bpf_map_lookup_elem(&counts, &zero);116if (count) {117*count += 1;118for (i = 0; i < num_metric && i < MAX_NUM_METRICS; i++)119fexit_update_maps(i, &readings[i]);120}121return 0;122}123124char LICENSE[] SEC("license") = "Dual BSD/GPL";125126127