xref: /openbmc/linux/tools/perf/util/bpf_skel/bperf_follower.bpf.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
17fac83aaSSong Liu // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
27fac83aaSSong Liu // Copyright (c) 2021 Facebook
3f7c4e85bSSong Liu #include "vmlinux.h"
47fac83aaSSong Liu #include <bpf/bpf_helpers.h>
57fac83aaSSong Liu #include <bpf/bpf_tracing.h>
67fac83aaSSong Liu #include "bperf_u.h"
77fac83aaSSong Liu 
8*5a897531SSong Liu struct {
9*5a897531SSong Liu 	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
10*5a897531SSong Liu 	__uint(key_size, sizeof(__u32));
11*5a897531SSong Liu 	__uint(value_size, sizeof(struct bpf_perf_event_value));
12*5a897531SSong Liu 	__uint(max_entries, 1);
13*5a897531SSong Liu } diff_readings SEC(".maps");
14*5a897531SSong Liu 
15*5a897531SSong Liu struct {
16*5a897531SSong Liu 	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
17*5a897531SSong Liu 	__uint(key_size, sizeof(__u32));
18*5a897531SSong Liu 	__uint(value_size, sizeof(struct bpf_perf_event_value));
19*5a897531SSong Liu 	__uint(max_entries, 1);
20*5a897531SSong Liu } accum_readings SEC(".maps");
217fac83aaSSong Liu 
227fac83aaSSong Liu struct {
237fac83aaSSong Liu 	__uint(type, BPF_MAP_TYPE_HASH);
247fac83aaSSong Liu 	__uint(key_size, sizeof(__u32));
257fac83aaSSong Liu 	__uint(value_size, sizeof(__u32));
267fac83aaSSong Liu } filter SEC(".maps");
277fac83aaSSong Liu 
287fac83aaSSong Liu enum bperf_filter_type type = 0;
297fac83aaSSong Liu int enabled = 0;
307fac83aaSSong Liu 
317fac83aaSSong Liu SEC("fexit/XXX")
BPF_PROG(fexit_XXX)327fac83aaSSong Liu int BPF_PROG(fexit_XXX)
337fac83aaSSong Liu {
347fac83aaSSong Liu 	struct bpf_perf_event_value *diff_val, *accum_val;
357fac83aaSSong Liu 	__u32 filter_key, zero = 0;
367fac83aaSSong Liu 	__u32 *accum_key;
377fac83aaSSong Liu 
387fac83aaSSong Liu 	if (!enabled)
397fac83aaSSong Liu 		return 0;
407fac83aaSSong Liu 
417fac83aaSSong Liu 	switch (type) {
427fac83aaSSong Liu 	case BPERF_FILTER_GLOBAL:
437fac83aaSSong Liu 		accum_key = &zero;
447fac83aaSSong Liu 		goto do_add;
457fac83aaSSong Liu 	case BPERF_FILTER_CPU:
467fac83aaSSong Liu 		filter_key = bpf_get_smp_processor_id();
477fac83aaSSong Liu 		break;
487fac83aaSSong Liu 	case BPERF_FILTER_PID:
497fac83aaSSong Liu 		filter_key = bpf_get_current_pid_tgid() & 0xffffffff;
507fac83aaSSong Liu 		break;
517fac83aaSSong Liu 	case BPERF_FILTER_TGID:
527fac83aaSSong Liu 		filter_key = bpf_get_current_pid_tgid() >> 32;
537fac83aaSSong Liu 		break;
547fac83aaSSong Liu 	default:
557fac83aaSSong Liu 		return 0;
567fac83aaSSong Liu 	}
577fac83aaSSong Liu 
587fac83aaSSong Liu 	accum_key = bpf_map_lookup_elem(&filter, &filter_key);
597fac83aaSSong Liu 	if (!accum_key)
607fac83aaSSong Liu 		return 0;
617fac83aaSSong Liu 
627fac83aaSSong Liu do_add:
637fac83aaSSong Liu 	diff_val = bpf_map_lookup_elem(&diff_readings, &zero);
647fac83aaSSong Liu 	if (!diff_val)
657fac83aaSSong Liu 		return 0;
667fac83aaSSong Liu 
677fac83aaSSong Liu 	accum_val = bpf_map_lookup_elem(&accum_readings, accum_key);
687fac83aaSSong Liu 	if (!accum_val)
697fac83aaSSong Liu 		return 0;
707fac83aaSSong Liu 
717fac83aaSSong Liu 	accum_val->counter += diff_val->counter;
727fac83aaSSong Liu 	accum_val->enabled += diff_val->enabled;
737fac83aaSSong Liu 	accum_val->running += diff_val->running;
747fac83aaSSong Liu 
757fac83aaSSong Liu 	return 0;
767fac83aaSSong Liu }
777fac83aaSSong Liu 
787fac83aaSSong Liu char LICENSE[] SEC("license") = "Dual BSD/GPL";
79