162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 262306a36Sopenharmony_ci// Copyright (c) 2021 Facebook 362306a36Sopenharmony_ci#include "vmlinux.h" 462306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 562306a36Sopenharmony_ci#include <bpf/bpf_tracing.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_cistruct { 862306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 962306a36Sopenharmony_ci __uint(key_size, sizeof(__u32)); 1062306a36Sopenharmony_ci __uint(value_size, sizeof(int)); 1162306a36Sopenharmony_ci __uint(map_flags, BPF_F_PRESERVE_ELEMS); 1262306a36Sopenharmony_ci} events SEC(".maps"); 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct { 1562306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); 1662306a36Sopenharmony_ci __uint(key_size, sizeof(__u32)); 1762306a36Sopenharmony_ci __uint(value_size, sizeof(struct bpf_perf_event_value)); 1862306a36Sopenharmony_ci __uint(max_entries, 1); 1962306a36Sopenharmony_ci} prev_readings SEC(".maps"); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistruct { 2262306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); 2362306a36Sopenharmony_ci __uint(key_size, sizeof(__u32)); 2462306a36Sopenharmony_ci __uint(value_size, sizeof(struct bpf_perf_event_value)); 2562306a36Sopenharmony_ci __uint(max_entries, 1); 2662306a36Sopenharmony_ci} diff_readings SEC(".maps"); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ciSEC("raw_tp/sched_switch") 2962306a36Sopenharmony_ciint BPF_PROG(on_switch) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci struct bpf_perf_event_value val, *prev_val, *diff_val; 3262306a36Sopenharmony_ci __u32 key = bpf_get_smp_processor_id(); 3362306a36Sopenharmony_ci __u32 zero = 0; 3462306a36Sopenharmony_ci long err; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci prev_val = bpf_map_lookup_elem(&prev_readings, &zero); 3762306a36Sopenharmony_ci if (!prev_val) 3862306a36Sopenharmony_ci return 0; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci diff_val = bpf_map_lookup_elem(&diff_readings, &zero); 4162306a36Sopenharmony_ci if (!diff_val) 4262306a36Sopenharmony_ci return 0; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci err = bpf_perf_event_read_value(&events, key, &val, sizeof(val)); 4562306a36Sopenharmony_ci if (err) 4662306a36Sopenharmony_ci return 0; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci diff_val->counter = val.counter - prev_val->counter; 4962306a36Sopenharmony_ci diff_val->enabled = val.enabled - prev_val->enabled; 5062306a36Sopenharmony_ci diff_val->running = val.running - prev_val->running; 5162306a36Sopenharmony_ci *prev_val = val; 5262306a36Sopenharmony_ci return 0; 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cichar LICENSE[] SEC("license") = "Dual BSD/GPL"; 56