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