root/tools/testing/selftests/bpf/progs/test_spin_lock.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SEC

   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 struct hmap_elem {
   8         volatile int cnt;
   9         struct bpf_spin_lock lock;
  10         int test_padding;
  11 };
  12 
  13 struct {
  14         __uint(type, BPF_MAP_TYPE_HASH);
  15         __uint(max_entries, 1);
  16         __type(key, int);
  17         __type(value, struct hmap_elem);
  18 } hmap SEC(".maps");
  19 
  20 struct cls_elem {
  21         struct bpf_spin_lock lock;
  22         volatile int cnt;
  23 };
  24 
  25 struct {
  26         __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);
  27         __type(key, struct bpf_cgroup_storage_key);
  28         __type(value, struct cls_elem);
  29 } cls_map SEC(".maps");
  30 
  31 struct bpf_vqueue {
  32         struct bpf_spin_lock lock;
  33         /* 4 byte hole */
  34         unsigned long long lasttime;
  35         int credit;
  36         unsigned int rate;
  37 };
  38 
  39 struct {
  40         __uint(type, BPF_MAP_TYPE_ARRAY);
  41         __uint(max_entries, 1);
  42         __type(key, int);
  43         __type(value, struct bpf_vqueue);
  44 } vqueue SEC(".maps");
  45 
  46 #define CREDIT_PER_NS(delta, rate) (((delta) * rate) >> 20)
  47 
  48 SEC("spin_lock_demo")
  49 int bpf_sping_lock_test(struct __sk_buff *skb)
  50 {
  51         volatile int credit = 0, max_credit = 100, pkt_len = 64;
  52         struct hmap_elem zero = {}, *val;
  53         unsigned long long curtime;
  54         struct bpf_vqueue *q;
  55         struct cls_elem *cls;
  56         int key = 0;
  57         int err = 0;
  58 
  59         val = bpf_map_lookup_elem(&hmap, &key);
  60         if (!val) {
  61                 bpf_map_update_elem(&hmap, &key, &zero, 0);
  62                 val = bpf_map_lookup_elem(&hmap, &key);
  63                 if (!val) {
  64                         err = 1;
  65                         goto err;
  66                 }
  67         }
  68         /* spin_lock in hash map run time test */
  69         bpf_spin_lock(&val->lock);
  70         if (val->cnt)
  71                 val->cnt--;
  72         else
  73                 val->cnt++;
  74         if (val->cnt != 0 && val->cnt != 1)
  75                 err = 1;
  76         bpf_spin_unlock(&val->lock);
  77 
  78         /* spin_lock in array. virtual queue demo */
  79         q = bpf_map_lookup_elem(&vqueue, &key);
  80         if (!q)
  81                 goto err;
  82         curtime = bpf_ktime_get_ns();
  83         bpf_spin_lock(&q->lock);
  84         q->credit += CREDIT_PER_NS(curtime - q->lasttime, q->rate);
  85         q->lasttime = curtime;
  86         if (q->credit > max_credit)
  87                 q->credit = max_credit;
  88         q->credit -= pkt_len;
  89         credit = q->credit;
  90         bpf_spin_unlock(&q->lock);
  91 
  92         /* spin_lock in cgroup local storage */
  93         cls = bpf_get_local_storage(&cls_map, 0);
  94         bpf_spin_lock(&cls->lock);
  95         cls->cnt++;
  96         bpf_spin_unlock(&cls->lock);
  97 
  98 err:
  99         return err;
 100 }
 101 char _license[] SEC("license") = "GPL";

/* [<][>][^][v][top][bottom][index][help] */