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
8struct {
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
15long hits;
16long gp_hits;
17long gp_times;
18long current_gp_start;
19long unexpected;
20bool postgp_seen;
21
22SEC("fentry/" SYS_PREFIX "sys_getpgid")
23int 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
42SEC("fentry/rcu_tasks_trace_pregp_step")
43int pregp_step(struct pt_regs *ctx)
44{
45	current_gp_start = bpf_ktime_get_ns();
46	return 0;
47}
48
49SEC("fentry/rcu_tasks_trace_postgp")
50int 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
67char _license[] SEC("license") = "GPL";
68