1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3 
4 #include "vmlinux.h"
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 struct {
9 	__uint(type, BPF_MAP_TYPE_TASK_STORAGE);
10 	__uint(map_flags, BPF_F_NO_PREALLOC);
11 	__type(key, int);
12 	__type(value, int);
13 } task_storage SEC(".maps");
14 
15 long hits;
16 long gp_hits;
17 long gp_times;
18 long current_gp_start;
19 long unexpected;
20 bool postgp_seen;
21 
22 SEC("fentry/" SYS_PREFIX "sys_getpgid")
23 int get_local(void *ctx)
24 {
25 	struct task_struct *task;
26 	int idx;
27 	int *s;
28 
29 	idx = 0;
30 	task = bpf_get_current_task_btf();
31 	s = bpf_task_storage_get(&task_storage, task, &idx,
32 				 BPF_LOCAL_STORAGE_GET_F_CREATE);
33 	if (!s)
34 		return 0;
35 
36 	*s = 3;
37 	bpf_task_storage_delete(&task_storage, task);
38 	__sync_add_and_fetch(&hits, 1);
39 	return 0;
40 }
41 
42 SEC("fentry/rcu_tasks_trace_pregp_step")
43 int pregp_step(struct pt_regs *ctx)
44 {
45 	current_gp_start = bpf_ktime_get_ns();
46 	return 0;
47 }
48 
49 SEC("fentry/rcu_tasks_trace_postgp")
50 int postgp(struct pt_regs *ctx)
51 {
52 	if (!current_gp_start && postgp_seen) {
53 		/* Will only happen if prog tracing rcu_tasks_trace_pregp_step doesn't
54 		 * execute before this prog
55 		 */
56 		__sync_add_and_fetch(&unexpected, 1);
57 		return 0;
58 	}
59 
60 	__sync_add_and_fetch(&gp_times, bpf_ktime_get_ns() - current_gp_start);
61 	__sync_add_and_fetch(&gp_hits, 1);
62 	current_gp_start = 0;
63 	postgp_seen = true;
64 	return 0;
65 }
66 
67 char _license[] SEC("license") = "GPL";
68