brintos

brintos / linux-shallow public Read only

0
0
Text · 2.9 KiB · 37c2d26 Raw
191 lines · c
1#include "bpf_experimental.h"2 3struct val_t {4	long b, c, d;5};6 7struct elem {8	long sum;9	struct val_t __percpu_kptr *pc;10};11 12struct {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 19void bpf_rcu_read_lock(void) __ksym;20void bpf_rcu_read_unlock(void) __ksym;21 22const volatile int nr_cpus;23 24/* Initialize the percpu object */25SEC("?fentry/bpf_fentry_test1")26int 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 */48SEC("?fentry/bpf_fentry_test2")49int 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 73int cpu0_field_d, sum_field_c;74int my_pid;75 76/* Summarize percpu data */77SEC("?fentry/bpf_fentry_test3")78int 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 */109SEC("?fentry/bpf_fentry_test4")110int 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 129SEC("?fentry.s/bpf_fentry_test1")130int 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);185out:186	bpf_rcu_read_unlock();187	return 0;188}189 190char _license[] SEC("license") = "GPL";191