162306a36Sopenharmony_ci/* Copyright (c) 2016, Facebook
262306a36Sopenharmony_ci *
362306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or
462306a36Sopenharmony_ci * modify it under the terms of version 2 of the GNU General Public
562306a36Sopenharmony_ci * License as published by the Free Software Foundation.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include "vmlinux.h"
862306a36Sopenharmony_ci#include <linux/version.h>
962306a36Sopenharmony_ci#include <bpf/bpf_helpers.h>
1062306a36Sopenharmony_ci#include <bpf/bpf_tracing.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifndef PERF_MAX_STACK_DEPTH
1362306a36Sopenharmony_ci#define PERF_MAX_STACK_DEPTH         127
1462306a36Sopenharmony_ci#endif
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct {
1762306a36Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_HASH);
1862306a36Sopenharmony_ci	__type(key, long);
1962306a36Sopenharmony_ci	__type(value, long);
2062306a36Sopenharmony_ci	__uint(max_entries, 1024);
2162306a36Sopenharmony_ci} my_map SEC(".maps");
2262306a36Sopenharmony_cistruct {
2362306a36Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
2462306a36Sopenharmony_ci	__uint(key_size, sizeof(long));
2562306a36Sopenharmony_ci	__uint(value_size, sizeof(long));
2662306a36Sopenharmony_ci	__uint(max_entries, 1024);
2762306a36Sopenharmony_ci} my_map2 SEC(".maps");
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistruct {
3062306a36Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_STACK_TRACE);
3162306a36Sopenharmony_ci	__uint(key_size, sizeof(u32));
3262306a36Sopenharmony_ci	__uint(value_size, PERF_MAX_STACK_DEPTH * sizeof(u64));
3362306a36Sopenharmony_ci	__uint(max_entries, 10000);
3462306a36Sopenharmony_ci} stackmap SEC(".maps");
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define PROG(foo) \
3762306a36Sopenharmony_ciint foo(struct pt_regs *ctx) \
3862306a36Sopenharmony_ci{ \
3962306a36Sopenharmony_ci	long v = PT_REGS_IP(ctx), *val; \
4062306a36Sopenharmony_ci\
4162306a36Sopenharmony_ci	val = bpf_map_lookup_elem(&my_map, &v); \
4262306a36Sopenharmony_ci	bpf_map_update_elem(&my_map, &v, &v, BPF_ANY); \
4362306a36Sopenharmony_ci	bpf_map_update_elem(&my_map2, &v, &v, BPF_ANY); \
4462306a36Sopenharmony_ci	bpf_map_delete_elem(&my_map2, &v); \
4562306a36Sopenharmony_ci	bpf_get_stackid(ctx, &stackmap, BPF_F_REUSE_STACKID); \
4662306a36Sopenharmony_ci	return 0; \
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* add kprobes to all possible *spin* functions */
5062306a36Sopenharmony_ciSEC("kprobe.multi/spin_*lock*")PROG(spin_lock)
5162306a36Sopenharmony_ciSEC("kprobe.multi/*_spin_on_owner")PROG(spin_on_owner)
5262306a36Sopenharmony_ciSEC("kprobe.multi/_raw_spin_*lock*")PROG(raw_spin_lock)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* and to inner bpf helpers */
5562306a36Sopenharmony_ciSEC("kprobe/htab_map_update_elem")PROG(p15)
5662306a36Sopenharmony_ciSEC("kprobe/__htab_percpu_map_update_elem")PROG(p16)
5762306a36Sopenharmony_ciSEC("kprobe/htab_map_alloc")PROG(p17)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cichar _license[] SEC("license") = "GPL";
6062306a36Sopenharmony_ciu32 _version SEC("version") = LINUX_VERSION_CODE;
61