1bd4aed0eSJiong Wang // SPDX-License-Identifier: GPL-2.0
2bd4aed0eSJiong Wang // Copyright (c) 2019 Facebook
3bd4aed0eSJiong Wang #include <linux/bpf.h>
4bd4aed0eSJiong Wang #include <linux/version.h>
5bd4aed0eSJiong Wang #include "bpf_helpers.h"
6bd4aed0eSJiong Wang 
7bd4aed0eSJiong Wang #define VAR_NUM 16
8bd4aed0eSJiong Wang 
9bd4aed0eSJiong Wang struct hmap_elem {
10bd4aed0eSJiong Wang 	struct bpf_spin_lock lock;
11bd4aed0eSJiong Wang 	int var[VAR_NUM];
12bd4aed0eSJiong Wang };
13bd4aed0eSJiong Wang 
14f6544074SAndrii Nakryiko struct {
15f6544074SAndrii Nakryiko 	__u32 type;
16f6544074SAndrii Nakryiko 	__u32 max_entries;
17f6544074SAndrii Nakryiko 	__u32 *key;
18f6544074SAndrii Nakryiko 	struct hmap_elem *value;
19f6544074SAndrii Nakryiko } hash_map SEC(".maps") = {
20bd4aed0eSJiong Wang 	.type = BPF_MAP_TYPE_HASH,
21bd4aed0eSJiong Wang 	.max_entries = 1,
22bd4aed0eSJiong Wang };
23bd4aed0eSJiong Wang 
24bd4aed0eSJiong Wang struct array_elem {
25bd4aed0eSJiong Wang 	struct bpf_spin_lock lock;
26bd4aed0eSJiong Wang 	int var[VAR_NUM];
27bd4aed0eSJiong Wang };
28bd4aed0eSJiong Wang 
29f6544074SAndrii Nakryiko struct {
30f6544074SAndrii Nakryiko 	__u32 type;
31f6544074SAndrii Nakryiko 	__u32 max_entries;
32f6544074SAndrii Nakryiko 	int *key;
33f6544074SAndrii Nakryiko 	struct array_elem *value;
34f6544074SAndrii Nakryiko } array_map SEC(".maps") = {
35bd4aed0eSJiong Wang 	.type = BPF_MAP_TYPE_ARRAY,
36bd4aed0eSJiong Wang 	.max_entries = 1,
37bd4aed0eSJiong Wang };
38bd4aed0eSJiong Wang 
39bd4aed0eSJiong Wang SEC("map_lock_demo")
40bd4aed0eSJiong Wang int bpf_map_lock_test(struct __sk_buff *skb)
41bd4aed0eSJiong Wang {
42bd4aed0eSJiong Wang 	struct hmap_elem zero = {}, *val;
43bd4aed0eSJiong Wang 	int rnd = bpf_get_prandom_u32();
44bd4aed0eSJiong Wang 	int key = 0, err = 1, i;
45bd4aed0eSJiong Wang 	struct array_elem *q;
46bd4aed0eSJiong Wang 
47bd4aed0eSJiong Wang 	val = bpf_map_lookup_elem(&hash_map, &key);
48bd4aed0eSJiong Wang 	if (!val)
49bd4aed0eSJiong Wang 		goto err;
50bd4aed0eSJiong Wang 	/* spin_lock in hash map */
51bd4aed0eSJiong Wang 	bpf_spin_lock(&val->lock);
52bd4aed0eSJiong Wang 	for (i = 0; i < VAR_NUM; i++)
53bd4aed0eSJiong Wang 		val->var[i] = rnd;
54bd4aed0eSJiong Wang 	bpf_spin_unlock(&val->lock);
55bd4aed0eSJiong Wang 
56bd4aed0eSJiong Wang 	/* spin_lock in array */
57bd4aed0eSJiong Wang 	q = bpf_map_lookup_elem(&array_map, &key);
58bd4aed0eSJiong Wang 	if (!q)
59bd4aed0eSJiong Wang 		goto err;
60bd4aed0eSJiong Wang 	bpf_spin_lock(&q->lock);
61bd4aed0eSJiong Wang 	for (i = 0; i < VAR_NUM; i++)
62bd4aed0eSJiong Wang 		q->var[i] = rnd;
63bd4aed0eSJiong Wang 	bpf_spin_unlock(&q->lock);
64bd4aed0eSJiong Wang 	err = 0;
65bd4aed0eSJiong Wang err:
66bd4aed0eSJiong Wang 	return err;
67bd4aed0eSJiong Wang }
68bd4aed0eSJiong Wang char _license[] SEC("license") = "GPL";
69