brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · f613dc9 Raw
118 lines · c
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)2// Copyright (c) 2021 Google3#include "vmlinux.h"4#include <bpf/bpf_helpers.h>5#include <bpf/bpf_tracing.h>6 7// This should be in sync with "util/ftrace.h"8#define NUM_BUCKET  229 10struct {11	__uint(type, BPF_MAP_TYPE_HASH);12	__uint(key_size, sizeof(__u64));13	__uint(value_size, sizeof(__u64));14	__uint(max_entries, 10000);15} functime SEC(".maps");16 17struct {18	__uint(type, BPF_MAP_TYPE_HASH);19	__uint(key_size, sizeof(__u32));20	__uint(value_size, sizeof(__u8));21	__uint(max_entries, 1);22} cpu_filter SEC(".maps");23 24struct {25	__uint(type, BPF_MAP_TYPE_HASH);26	__uint(key_size, sizeof(__u32));27	__uint(value_size, sizeof(__u8));28	__uint(max_entries, 1);29} task_filter SEC(".maps");30 31struct {32	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);33	__uint(key_size, sizeof(__u32));34	__uint(value_size, sizeof(__u64));35	__uint(max_entries, NUM_BUCKET);36} latency SEC(".maps");37 38 39int enabled = 0;40 41const volatile int has_cpu = 0;42const volatile int has_task = 0;43const volatile int use_nsec = 0;44 45SEC("kprobe/func")46int BPF_PROG(func_begin)47{48	__u64 key, now;49 50	if (!enabled)51		return 0;52 53	key = bpf_get_current_pid_tgid();54 55	if (has_cpu) {56		__u32 cpu = bpf_get_smp_processor_id();57		__u8 *ok;58 59		ok = bpf_map_lookup_elem(&cpu_filter, &cpu);60		if (!ok)61			return 0;62	}63 64	if (has_task) {65		__u32 pid = key & 0xffffffff;66		__u8 *ok;67 68		ok = bpf_map_lookup_elem(&task_filter, &pid);69		if (!ok)70			return 0;71	}72 73	now = bpf_ktime_get_ns();74 75	// overwrite timestamp for nested functions76	bpf_map_update_elem(&functime, &key, &now, BPF_ANY);77	return 0;78}79 80SEC("kretprobe/func")81int BPF_PROG(func_end)82{83	__u64 tid;84	__u64 *start;85	__u64 cmp_base = use_nsec ? 1 : 1000;86 87	if (!enabled)88		return 0;89 90	tid = bpf_get_current_pid_tgid();91 92	start = bpf_map_lookup_elem(&functime, &tid);93	if (start) {94		__s64 delta = bpf_ktime_get_ns() - *start;95		__u32 key;96		__u64 *hist;97 98		bpf_map_delete_elem(&functime, &tid);99 100		if (delta < 0)101			return 0;102 103		// calculate index using delta104		for (key = 0; key < (NUM_BUCKET - 1); key++) {105			if (delta < (cmp_base << key))106				break;107		}108 109		hist = bpf_map_lookup_elem(&latency, &key);110		if (!hist)111			return 0;112 113		*hist += 1;114	}115 116	return 0;117}118