~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/percpu_alloc_array.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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_ARRAY);
 14         __uint(max_entries, 1);
 15         __type(key, int);
 16         __type(value, struct elem);
 17 } array SEC(".maps");
 18 
 19 void bpf_rcu_read_lock(void) __ksym;
 20 void bpf_rcu_read_unlock(void) __ksym;
 21 
 22 const volatile int nr_cpus;
 23 
 24 /* Initialize the percpu object */
 25 SEC("?fentry/bpf_fentry_test1")
 26 int BPF_PROG(test_array_map_1)
 27 {
 28         struct val_t __percpu_kptr *p;
 29         struct elem *e;
 30         int index = 0;
 31 
 32         e = bpf_map_lookup_elem(&array, &index);
 33         if (!e)
 34                 return 0;
 35 
 36         p = bpf_percpu_obj_new(struct val_t);
 37         if (!p)
 38                 return 0;
 39 
 40         p = bpf_kptr_xchg(&e->pc, p);
 41         if (p)
 42                 bpf_percpu_obj_drop(p);
 43 
 44         return 0;
 45 }
 46 
 47 /* Update percpu data */
 48 SEC("?fentry/bpf_fentry_test2")
 49 int BPF_PROG(test_array_map_2)
 50 {
 51         struct val_t __percpu_kptr *p;
 52         struct val_t *v;
 53         struct elem *e;
 54         int index = 0;
 55 
 56         e = bpf_map_lookup_elem(&array, &index);
 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 
 70         return 0;
 71 }
 72 
 73 int cpu0_field_d, sum_field_c;
 74 int my_pid;
 75 
 76 /* Summarize percpu data */
 77 SEC("?fentry/bpf_fentry_test3")
 78 int BPF_PROG(test_array_map_3)
 79 {
 80         struct val_t __percpu_kptr *p;
 81         int i, index = 0;
 82         struct val_t *v;
 83         struct elem *e;
 84 
 85         if ((bpf_get_current_pid_tgid() >> 32) != my_pid)
 86                 return 0;
 87 
 88         e = bpf_map_lookup_elem(&array, &index);
 89         if (!e)
 90                 return 0;
 91 
 92         p = e->pc;
 93         if (!p)
 94                 return 0;
 95 
 96         bpf_for(i, 0, nr_cpus) {
 97                 v = bpf_per_cpu_ptr(p, i);
 98                 if (v) {
 99                         if (i == 0)
100                                 cpu0_field_d = v->d;
101                         sum_field_c += v->c;
102                 }
103         }
104 
105         return 0;
106 }
107 
108 /* Explicitly free allocated percpu data */
109 SEC("?fentry/bpf_fentry_test4")
110 int BPF_PROG(test_array_map_4)
111 {
112         struct val_t __percpu_kptr *p;
113         struct elem *e;
114         int index = 0;
115 
116         e = bpf_map_lookup_elem(&array, &index);
117         if (!e)
118                 return 0;
119 
120         /* delete */
121         p = bpf_kptr_xchg(&e->pc, NULL);
122         if (p) {
123                 bpf_percpu_obj_drop(p);
124         }
125 
126         return 0;
127 }
128 
129 SEC("?fentry.s/bpf_fentry_test1")
130 int BPF_PROG(test_array_map_10)
131 {
132         struct val_t __percpu_kptr *p, *p1;
133         int i, index = 0;
134         struct val_t *v;
135         struct elem *e;
136 
137         if ((bpf_get_current_pid_tgid() >> 32) != my_pid)
138                 return 0;
139 
140         e = bpf_map_lookup_elem(&array, &index);
141         if (!e)
142                 return 0;
143 
144         bpf_rcu_read_lock();
145         p = e->pc;
146         if (!p) {
147                 p = bpf_percpu_obj_new(struct val_t);
148                 if (!p)
149                         goto out;
150 
151                 p1 = bpf_kptr_xchg(&e->pc, p);
152                 if (p1) {
153                         /* race condition */
154                         bpf_percpu_obj_drop(p1);
155                 }
156         }
157 
158         v = bpf_this_cpu_ptr(p);
159         v->c = 3;
160         v = bpf_this_cpu_ptr(p);
161         v->c = 0;
162 
163         v = bpf_per_cpu_ptr(p, 0);
164         if (!v)
165                 goto out;
166         v->c = 1;
167         v->d = 2;
168 
169         /* delete */
170         p1 = bpf_kptr_xchg(&e->pc, NULL);
171         if (!p1)
172                 goto out;
173 
174         bpf_for(i, 0, nr_cpus) {
175                 v = bpf_per_cpu_ptr(p, i);
176                 if (v) {
177                         if (i == 0)
178                                 cpu0_field_d = v->d;
179                         sum_field_c += v->c;
180                 }
181         }
182 
183         /* finally release p */
184         bpf_percpu_obj_drop(p1);
185 out:
186         bpf_rcu_read_unlock();
187         return 0;
188 }
189 
190 char _license[] SEC("license") = "GPL";
191 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php