11da4864cSSong Liu // SPDX-License-Identifier: GPL-2.0
21da4864cSSong Liu // Copyright (c) 2020 Facebook
31da4864cSSong Liu #include "vmlinux.h"
41da4864cSSong Liu #include <bpf/bpf_helpers.h>
51da4864cSSong Liu 
61da4864cSSong Liu #ifndef PERF_MAX_STACK_DEPTH
71da4864cSSong Liu #define PERF_MAX_STACK_DEPTH         127
81da4864cSSong Liu #endif
91da4864cSSong Liu 
101da4864cSSong Liu typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH];
111da4864cSSong Liu struct {
121da4864cSSong Liu 	__uint(type, BPF_MAP_TYPE_STACK_TRACE);
131da4864cSSong Liu 	__uint(max_entries, 16384);
14bd368cb5SHengqi Chen 	__type(key, __u32);
15bd368cb5SHengqi Chen 	__type(value, stack_trace_t);
161da4864cSSong Liu } stackmap SEC(".maps");
171da4864cSSong Liu 
181da4864cSSong Liu struct {
191da4864cSSong Liu 	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
201da4864cSSong Liu 	__uint(max_entries, 1);
211da4864cSSong Liu 	__type(key, __u32);
221da4864cSSong Liu 	__type(value, stack_trace_t);
231da4864cSSong Liu } stackdata_map SEC(".maps");
241da4864cSSong Liu 
251da4864cSSong Liu long stackid_kernel = 1;
261da4864cSSong Liu long stackid_user = 1;
271da4864cSSong Liu long stack_kernel = 1;
281da4864cSSong Liu long stack_user = 1;
291da4864cSSong Liu 
301da4864cSSong Liu SEC("perf_event")
oncpu(void * ctx)311da4864cSSong Liu int oncpu(void *ctx)
321da4864cSSong Liu {
331da4864cSSong Liu 	stack_trace_t *trace;
341da4864cSSong Liu 	__u32 key = 0;
351da4864cSSong Liu 	long val;
361da4864cSSong Liu 
371da4864cSSong Liu 	val = bpf_get_stackid(ctx, &stackmap, 0);
38*658d8768SYuntao Wang 	if (val >= 0)
391da4864cSSong Liu 		stackid_kernel = 2;
401da4864cSSong Liu 	val = bpf_get_stackid(ctx, &stackmap, BPF_F_USER_STACK);
41*658d8768SYuntao Wang 	if (val >= 0)
421da4864cSSong Liu 		stackid_user = 2;
431da4864cSSong Liu 
441da4864cSSong Liu 	trace = bpf_map_lookup_elem(&stackdata_map, &key);
451da4864cSSong Liu 	if (!trace)
461da4864cSSong Liu 		return 0;
471da4864cSSong Liu 
481da4864cSSong Liu 	val = bpf_get_stack(ctx, trace, sizeof(stack_trace_t), 0);
491da4864cSSong Liu 	if (val > 0)
501da4864cSSong Liu 		stack_kernel = 2;
511da4864cSSong Liu 
521da4864cSSong Liu 	val = bpf_get_stack(ctx, trace, sizeof(stack_trace_t), BPF_F_USER_STACK);
531da4864cSSong Liu 	if (val > 0)
541da4864cSSong Liu 		stack_user = 2;
551da4864cSSong Liu 
561da4864cSSong Liu 	return 0;
571da4864cSSong Liu }
581da4864cSSong Liu 
591da4864cSSong Liu char LICENSE[] SEC("license") = "GPL";
60