3087c61ed2
As the sched:sched_switch tracepoint args are derived from the kernel, we'd better make it same with the kernel. So the macro TASK_COMM_LEN is converted to type enum, then all the BPF programs can get it through BTF. The BPF program which wants to use TASK_COMM_LEN should include the header vmlinux.h. Regarding the test_stacktrace_map and test_tracepoint, as the type defined in linux/bpf.h are also defined in vmlinux.h, so we don't need to include linux/bpf.h again. Link: https://lkml.kernel.org/r/20211120112738.45980-8-laoar.shao@gmail.com Signed-off-by: Yafang Shao <laoar.shao@gmail.com> Acked-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: David Hildenbrand <david@redhat.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com> Cc: Michal Miroslaw <mirq-linux@rere.qmqm.pl> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: David Hildenbrand <david@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Kees Cook <keescook@chromium.org> Cc: Petr Mladek <pmladek@suse.com> Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com> Cc: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
77 lines
1.7 KiB
C
77 lines
1.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// Copyright (c) 2018 Facebook
|
|
|
|
#include <vmlinux.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
|
|
#ifndef PERF_MAX_STACK_DEPTH
|
|
#define PERF_MAX_STACK_DEPTH 127
|
|
#endif
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_ARRAY);
|
|
__uint(max_entries, 1);
|
|
__type(key, __u32);
|
|
__type(value, __u32);
|
|
} control_map SEC(".maps");
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_HASH);
|
|
__uint(max_entries, 16384);
|
|
__type(key, __u32);
|
|
__type(value, __u32);
|
|
} stackid_hmap SEC(".maps");
|
|
|
|
typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH];
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_STACK_TRACE);
|
|
__uint(max_entries, 16384);
|
|
__type(key, __u32);
|
|
__type(value, stack_trace_t);
|
|
} stackmap SEC(".maps");
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_ARRAY);
|
|
__uint(max_entries, 16384);
|
|
__type(key, __u32);
|
|
__type(value, stack_trace_t);
|
|
} stack_amap SEC(".maps");
|
|
|
|
/* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */
|
|
struct sched_switch_args {
|
|
unsigned long long pad;
|
|
char prev_comm[TASK_COMM_LEN];
|
|
int prev_pid;
|
|
int prev_prio;
|
|
long long prev_state;
|
|
char next_comm[TASK_COMM_LEN];
|
|
int next_pid;
|
|
int next_prio;
|
|
};
|
|
|
|
SEC("tracepoint/sched/sched_switch")
|
|
int oncpu(struct sched_switch_args *ctx)
|
|
{
|
|
__u32 max_len = PERF_MAX_STACK_DEPTH * sizeof(__u64);
|
|
__u32 key = 0, val = 0, *value_p;
|
|
void *stack_p;
|
|
|
|
value_p = bpf_map_lookup_elem(&control_map, &key);
|
|
if (value_p && *value_p)
|
|
return 0; /* skip if non-zero *value_p */
|
|
|
|
/* The size of stackmap and stackid_hmap should be the same */
|
|
key = bpf_get_stackid(ctx, &stackmap, 0);
|
|
if ((int)key >= 0) {
|
|
bpf_map_update_elem(&stackid_hmap, &key, &val, 0);
|
|
stack_p = bpf_map_lookup_elem(&stack_amap, &key);
|
|
if (stack_p)
|
|
bpf_get_stack(ctx, stack_p, max_len, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char _license[] SEC("license") = "GPL";
|