1 | #include "bpf_experimental.h" |
2 | |
3 | struct val_t { |
4 | long b, c, d; |
5 | }; |
6 | |
7 | struct elem { |
8 | long sum; |
9 | struct val_t __percpu_kptr *pc; |
10 | }; |
11 | |
12 | struct { |
13 | __uint(type, BPF_MAP_TYPE_CGRP_STORAGE); |
14 | __uint(map_flags, BPF_F_NO_PREALLOC); |
15 | __type(key, int); |
16 | __type(value, struct elem); |
17 | } cgrp SEC(".maps" ); |
18 | |
19 | const volatile int nr_cpus; |
20 | |
21 | /* Initialize the percpu object */ |
22 | SEC("fentry/bpf_fentry_test1" ) |
23 | int BPF_PROG(test_cgrp_local_storage_1) |
24 | { |
25 | struct task_struct *task; |
26 | struct val_t __percpu_kptr *p; |
27 | struct elem *e; |
28 | |
29 | task = bpf_get_current_task_btf(); |
30 | e = bpf_cgrp_storage_get(&cgrp, task->cgroups->dfl_cgrp, 0, |
31 | BPF_LOCAL_STORAGE_GET_F_CREATE); |
32 | if (!e) |
33 | return 0; |
34 | |
35 | p = bpf_percpu_obj_new(struct val_t); |
36 | if (!p) |
37 | return 0; |
38 | |
39 | p = bpf_kptr_xchg(&e->pc, p); |
40 | if (p) |
41 | bpf_percpu_obj_drop(p); |
42 | |
43 | return 0; |
44 | } |
45 | |
46 | /* Percpu data collection */ |
47 | SEC("fentry/bpf_fentry_test2" ) |
48 | int BPF_PROG(test_cgrp_local_storage_2) |
49 | { |
50 | struct task_struct *task; |
51 | struct val_t __percpu_kptr *p; |
52 | struct val_t *v; |
53 | struct elem *e; |
54 | |
55 | task = bpf_get_current_task_btf(); |
56 | e = bpf_cgrp_storage_get(&cgrp, task->cgroups->dfl_cgrp, 0, 0); |
57 | if (!e) |
58 | return 0; |
59 | |
60 | p = e->pc; |
61 | if (!p) |
62 | return 0; |
63 | |
64 | v = bpf_per_cpu_ptr(p, 0); |
65 | if (!v) |
66 | return 0; |
67 | v->c = 1; |
68 | v->d = 2; |
69 | return 0; |
70 | } |
71 | |
72 | int cpu0_field_d, sum_field_c; |
73 | int my_pid; |
74 | |
75 | /* Summarize percpu data collection */ |
76 | SEC("fentry/bpf_fentry_test3" ) |
77 | int BPF_PROG(test_cgrp_local_storage_3) |
78 | { |
79 | struct task_struct *task; |
80 | struct val_t __percpu_kptr *p; |
81 | struct val_t *v; |
82 | struct elem *e; |
83 | int i; |
84 | |
85 | if ((bpf_get_current_pid_tgid() >> 32) != my_pid) |
86 | return 0; |
87 | |
88 | task = bpf_get_current_task_btf(); |
89 | e = bpf_cgrp_storage_get(&cgrp, task->cgroups->dfl_cgrp, 0, 0); |
90 | if (!e) |
91 | return 0; |
92 | |
93 | p = e->pc; |
94 | if (!p) |
95 | return 0; |
96 | |
97 | bpf_for(i, 0, nr_cpus) { |
98 | v = bpf_per_cpu_ptr(p, i); |
99 | if (v) { |
100 | if (i == 0) |
101 | cpu0_field_d = v->d; |
102 | sum_field_c += v->c; |
103 | } |
104 | } |
105 | |
106 | return 0; |
107 | } |
108 | |
109 | char _license[] SEC("license" ) = "GPL" ; |
110 | |