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

source code of linux/tools/testing/selftests/bpf/progs/local_storage_rcu_tasks_trace_bench.c