1*e1cc1f39SNamhyung Kim // SPDX-License-Identifier: GPL-2.0
2*e1cc1f39SNamhyung Kim #include <vmlinux.h>
3*e1cc1f39SNamhyung Kim #include <bpf/bpf_helpers.h>
4*e1cc1f39SNamhyung Kim 
5*e1cc1f39SNamhyung Kim #define TEST_STACK_DEPTH	2
6*e1cc1f39SNamhyung Kim #define TEST_MAX_ENTRIES	16384
7*e1cc1f39SNamhyung Kim 
8*e1cc1f39SNamhyung Kim typedef __u64 stack_trace_t[TEST_STACK_DEPTH];
9*e1cc1f39SNamhyung Kim 
10*e1cc1f39SNamhyung Kim struct {
11*e1cc1f39SNamhyung Kim 	__uint(type, BPF_MAP_TYPE_STACK_TRACE);
12*e1cc1f39SNamhyung Kim 	__uint(max_entries, TEST_MAX_ENTRIES);
13*e1cc1f39SNamhyung Kim 	__type(key, __u32);
14*e1cc1f39SNamhyung Kim 	__type(value, stack_trace_t);
15*e1cc1f39SNamhyung Kim } stackmap SEC(".maps");
16*e1cc1f39SNamhyung Kim 
17*e1cc1f39SNamhyung Kim struct {
18*e1cc1f39SNamhyung Kim 	__uint(type, BPF_MAP_TYPE_HASH);
19*e1cc1f39SNamhyung Kim 	__uint(max_entries, TEST_MAX_ENTRIES);
20*e1cc1f39SNamhyung Kim 	__type(key, __u32);
21*e1cc1f39SNamhyung Kim 	__type(value, __u32);
22*e1cc1f39SNamhyung Kim } stackid_hmap SEC(".maps");
23*e1cc1f39SNamhyung Kim 
24*e1cc1f39SNamhyung Kim struct {
25*e1cc1f39SNamhyung Kim 	__uint(type, BPF_MAP_TYPE_ARRAY);
26*e1cc1f39SNamhyung Kim 	__uint(max_entries, TEST_MAX_ENTRIES);
27*e1cc1f39SNamhyung Kim 	__type(key, __u32);
28*e1cc1f39SNamhyung Kim 	__type(value, stack_trace_t);
29*e1cc1f39SNamhyung Kim } stack_amap SEC(".maps");
30*e1cc1f39SNamhyung Kim 
31*e1cc1f39SNamhyung Kim int pid = 0;
32*e1cc1f39SNamhyung Kim int control = 0;
33*e1cc1f39SNamhyung Kim int failed = 0;
34*e1cc1f39SNamhyung Kim 
35*e1cc1f39SNamhyung Kim SEC("tracepoint/sched/sched_switch")
oncpu(struct trace_event_raw_sched_switch * ctx)36*e1cc1f39SNamhyung Kim int oncpu(struct trace_event_raw_sched_switch *ctx)
37*e1cc1f39SNamhyung Kim {
38*e1cc1f39SNamhyung Kim 	__u32 max_len = TEST_STACK_DEPTH * sizeof(__u64);
39*e1cc1f39SNamhyung Kim 	__u32 key = 0, val = 0;
40*e1cc1f39SNamhyung Kim 	__u64 *stack_p;
41*e1cc1f39SNamhyung Kim 
42*e1cc1f39SNamhyung Kim 	if (pid != (bpf_get_current_pid_tgid() >> 32))
43*e1cc1f39SNamhyung Kim 		return 0;
44*e1cc1f39SNamhyung Kim 
45*e1cc1f39SNamhyung Kim 	if (control)
46*e1cc1f39SNamhyung Kim 		return 0;
47*e1cc1f39SNamhyung Kim 
48*e1cc1f39SNamhyung Kim 	/* it should allow skipping whole buffer size entries */
49*e1cc1f39SNamhyung Kim 	key = bpf_get_stackid(ctx, &stackmap, TEST_STACK_DEPTH);
50*e1cc1f39SNamhyung Kim 	if ((int)key >= 0) {
51*e1cc1f39SNamhyung Kim 		/* The size of stackmap and stack_amap should be the same */
52*e1cc1f39SNamhyung Kim 		bpf_map_update_elem(&stackid_hmap, &key, &val, 0);
53*e1cc1f39SNamhyung Kim 		stack_p = bpf_map_lookup_elem(&stack_amap, &key);
54*e1cc1f39SNamhyung Kim 		if (stack_p) {
55*e1cc1f39SNamhyung Kim 			bpf_get_stack(ctx, stack_p, max_len, TEST_STACK_DEPTH);
56*e1cc1f39SNamhyung Kim 			/* it wrongly skipped all the entries and filled zero */
57*e1cc1f39SNamhyung Kim 			if (stack_p[0] == 0)
58*e1cc1f39SNamhyung Kim 				failed = 1;
59*e1cc1f39SNamhyung Kim 		}
60*e1cc1f39SNamhyung Kim 	} else {
61*e1cc1f39SNamhyung Kim 		/* old kernel doesn't support skipping that many entries */
62*e1cc1f39SNamhyung Kim 		failed = 2;
63*e1cc1f39SNamhyung Kim 	}
64*e1cc1f39SNamhyung Kim 
65*e1cc1f39SNamhyung Kim 	return 0;
66*e1cc1f39SNamhyung Kim }
67*e1cc1f39SNamhyung Kim 
68*e1cc1f39SNamhyung Kim char _license[] SEC("license") = "GPL";
69