1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2023. Huawei Technologies Co., Ltd */
3#include <vmlinux.h>
4#include <bpf/bpf_tracing.h>
5#include <bpf/bpf_helpers.h>
6
7#include "bpf_experimental.h"
8
9struct bin_data {
10	char data[256];
11	struct bpf_spin_lock lock;
12};
13
14struct map_value {
15	struct bin_data __kptr * data;
16};
17
18struct {
19	__uint(type, BPF_MAP_TYPE_ARRAY);
20	__type(key, int);
21	__type(value, struct map_value);
22	__uint(max_entries, 2048);
23} array SEC(".maps");
24
25char _license[] SEC("license") = "GPL";
26
27bool nomem_err = false;
28
29static int del_array(unsigned int i, int *from)
30{
31	struct map_value *value;
32	struct bin_data *old;
33
34	value = bpf_map_lookup_elem(&array, from);
35	if (!value)
36		return 1;
37
38	old = bpf_kptr_xchg(&value->data, NULL);
39	if (old)
40		bpf_obj_drop(old);
41
42	(*from)++;
43	return 0;
44}
45
46static int add_array(unsigned int i, int *from)
47{
48	struct bin_data *old, *new;
49	struct map_value *value;
50
51	value = bpf_map_lookup_elem(&array, from);
52	if (!value)
53		return 1;
54
55	new = bpf_obj_new(typeof(*new));
56	if (!new) {
57		nomem_err = true;
58		return 1;
59	}
60
61	old = bpf_kptr_xchg(&value->data, new);
62	if (old)
63		bpf_obj_drop(old);
64
65	(*from)++;
66	return 0;
67}
68
69static void del_then_add_array(int from)
70{
71	int i;
72
73	i = from;
74	bpf_loop(512, del_array, &i, 0);
75
76	i = from;
77	bpf_loop(512, add_array, &i, 0);
78}
79
80SEC("fentry/bpf_fentry_test1")
81int BPF_PROG2(test0, int, a)
82{
83	del_then_add_array(0);
84	return 0;
85}
86
87SEC("fentry/bpf_fentry_test2")
88int BPF_PROG2(test1, int, a, u64, b)
89{
90	del_then_add_array(512);
91	return 0;
92}
93
94SEC("fentry/bpf_fentry_test3")
95int BPF_PROG2(test2, char, a, int, b, u64, c)
96{
97	del_then_add_array(1024);
98	return 0;
99}
100
101SEC("fentry/bpf_fentry_test4")
102int BPF_PROG2(test3, void *, a, char, b, int, c, u64, d)
103{
104	del_then_add_array(1536);
105	return 0;
106}
107