| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 184 | bpf_percpu_obj_drop(p1);
|
| 185 | out:
|
| 186 | bpf_rcu_read_unlock();
|
| 187 | return 0;
|
| 188 | }
|
| 189 |
|
| 190 | struct {
|
| 191 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
| 192 | __uint(max_entries, 2);
|
| 193 | __type(key, int);
|
| 194 | __type(value, u32);
|
| 195 | } percpu SEC(".maps");
|
| 196 |
|
| 197 | SEC("?fentry/bpf_fentry_test1")
|
| 198 | int BPF_PROG(test_percpu_array, int x)
|
| 199 | {
|
| 200 | u64 value = 0xDEADC0DE;
|
| 201 | int key = 0;
|
| 202 |
|
| 203 | bpf_map_update_elem(&percpu, &key, &value, BPF_ANY);
|
| 204 | return 0;
|
| 205 | }
|
| 206 |
|
| 207 | struct {
|
| 208 | __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE);
|
| 209 | __type(key, struct bpf_cgroup_storage_key);
|
| 210 | __type(value, u32);
|
| 211 | } percpu_cgroup_storage SEC(".maps");
|
| 212 |
|
| 213 | SEC("cgroup_skb/egress")
|
| 214 | int cgroup_egress(struct __sk_buff *skb)
|
| 215 | {
|
| 216 | u32 *val = bpf_get_local_storage(&percpu_cgroup_storage, 0);
|
| 217 |
|
| 218 | *val = 1;
|
| 219 | return 1;
|
| 220 | }
|
| 221 |
|
| 222 | char _license[] SEC("license") = "GPL";
|