Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2019 Facebook
0003 #include <linux/bpf.h>
0004 #include <linux/version.h>
0005 #include <bpf/bpf_helpers.h>
0006 
0007 struct hmap_elem {
0008     volatile int cnt;
0009     struct bpf_spin_lock lock;
0010     int test_padding;
0011 };
0012 
0013 struct {
0014     __uint(type, BPF_MAP_TYPE_HASH);
0015     __uint(max_entries, 1);
0016     __type(key, int);
0017     __type(value, struct hmap_elem);
0018 } hmap SEC(".maps");
0019 
0020 struct cls_elem {
0021     struct bpf_spin_lock lock;
0022     volatile int cnt;
0023 };
0024 
0025 struct {
0026     __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);
0027     __type(key, struct bpf_cgroup_storage_key);
0028     __type(value, struct cls_elem);
0029 } cls_map SEC(".maps");
0030 
0031 struct bpf_vqueue {
0032     struct bpf_spin_lock lock;
0033     /* 4 byte hole */
0034     unsigned long long lasttime;
0035     int credit;
0036     unsigned int rate;
0037 };
0038 
0039 struct {
0040     __uint(type, BPF_MAP_TYPE_ARRAY);
0041     __uint(max_entries, 1);
0042     __type(key, int);
0043     __type(value, struct bpf_vqueue);
0044 } vqueue SEC(".maps");
0045 
0046 #define CREDIT_PER_NS(delta, rate) (((delta) * rate) >> 20)
0047 
0048 SEC("tc")
0049 int bpf_sping_lock_test(struct __sk_buff *skb)
0050 {
0051     volatile int credit = 0, max_credit = 100, pkt_len = 64;
0052     struct hmap_elem zero = {}, *val;
0053     unsigned long long curtime;
0054     struct bpf_vqueue *q;
0055     struct cls_elem *cls;
0056     int key = 0;
0057     int err = 0;
0058 
0059     val = bpf_map_lookup_elem(&hmap, &key);
0060     if (!val) {
0061         bpf_map_update_elem(&hmap, &key, &zero, 0);
0062         val = bpf_map_lookup_elem(&hmap, &key);
0063         if (!val) {
0064             err = 1;
0065             goto err;
0066         }
0067     }
0068     /* spin_lock in hash map run time test */
0069     bpf_spin_lock(&val->lock);
0070     if (val->cnt)
0071         val->cnt--;
0072     else
0073         val->cnt++;
0074     if (val->cnt != 0 && val->cnt != 1)
0075         err = 1;
0076     bpf_spin_unlock(&val->lock);
0077 
0078     /* spin_lock in array. virtual queue demo */
0079     q = bpf_map_lookup_elem(&vqueue, &key);
0080     if (!q)
0081         goto err;
0082     curtime = bpf_ktime_get_ns();
0083     bpf_spin_lock(&q->lock);
0084     q->credit += CREDIT_PER_NS(curtime - q->lasttime, q->rate);
0085     q->lasttime = curtime;
0086     if (q->credit > max_credit)
0087         q->credit = max_credit;
0088     q->credit -= pkt_len;
0089     credit = q->credit;
0090     bpf_spin_unlock(&q->lock);
0091 
0092     /* spin_lock in cgroup local storage */
0093     cls = bpf_get_local_storage(&cls_map, 0);
0094     bpf_spin_lock(&cls->lock);
0095     cls->cnt++;
0096     bpf_spin_unlock(&cls->lock);
0097 
0098 err:
0099     return err;
0100 }
0101 char _license[] SEC("license") = "GPL";