1cb1c9dddSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
2cb1c9dddSAndrii Nakryiko // Copyright (c) 2020 Facebook
3cb1c9dddSAndrii Nakryiko
4cb1c9dddSAndrii Nakryiko #include <linux/bpf.h>
5cb1c9dddSAndrii Nakryiko #include <bpf/bpf_helpers.h>
6cb1c9dddSAndrii Nakryiko
7cb1c9dddSAndrii Nakryiko char _license[] SEC("license") = "GPL";
8cb1c9dddSAndrii Nakryiko
9cb1c9dddSAndrii Nakryiko struct sample {
10cb1c9dddSAndrii Nakryiko int pid;
11cb1c9dddSAndrii Nakryiko int seq;
12cb1c9dddSAndrii Nakryiko long value;
13cb1c9dddSAndrii Nakryiko char comm[16];
14cb1c9dddSAndrii Nakryiko };
15cb1c9dddSAndrii Nakryiko
16cb1c9dddSAndrii Nakryiko struct ringbuf_map {
17cb1c9dddSAndrii Nakryiko __uint(type, BPF_MAP_TYPE_RINGBUF);
18*7b3a0638SAndrii Nakryiko /* libbpf will adjust to valid page size */
19*7b3a0638SAndrii Nakryiko __uint(max_entries, 1000);
20cb1c9dddSAndrii Nakryiko } ringbuf1 SEC(".maps"),
21cb1c9dddSAndrii Nakryiko ringbuf2 SEC(".maps");
22cb1c9dddSAndrii Nakryiko
23cb1c9dddSAndrii Nakryiko struct {
24cb1c9dddSAndrii Nakryiko __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
25cb1c9dddSAndrii Nakryiko __uint(max_entries, 4);
26cb1c9dddSAndrii Nakryiko __type(key, int);
27cb1c9dddSAndrii Nakryiko __array(values, struct ringbuf_map);
28cb1c9dddSAndrii Nakryiko } ringbuf_arr SEC(".maps") = {
29cb1c9dddSAndrii Nakryiko .values = {
30cb1c9dddSAndrii Nakryiko [0] = &ringbuf1,
31cb1c9dddSAndrii Nakryiko [2] = &ringbuf2,
32cb1c9dddSAndrii Nakryiko },
33cb1c9dddSAndrii Nakryiko };
34cb1c9dddSAndrii Nakryiko
35cfc0889cSYauheni Kaliuta struct {
36cfc0889cSYauheni Kaliuta __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
37cfc0889cSYauheni Kaliuta __uint(max_entries, 1);
38cfc0889cSYauheni Kaliuta __type(key, int);
39cfc0889cSYauheni Kaliuta __array(values, struct ringbuf_map);
40cfc0889cSYauheni Kaliuta } ringbuf_hash SEC(".maps") = {
41cfc0889cSYauheni Kaliuta .values = {
42cfc0889cSYauheni Kaliuta [0] = &ringbuf1,
43cfc0889cSYauheni Kaliuta },
44cfc0889cSYauheni Kaliuta };
45cfc0889cSYauheni Kaliuta
46cb1c9dddSAndrii Nakryiko /* inputs */
47cb1c9dddSAndrii Nakryiko int pid = 0;
48cb1c9dddSAndrii Nakryiko int target_ring = 0;
49cb1c9dddSAndrii Nakryiko long value = 0;
50cb1c9dddSAndrii Nakryiko
51cb1c9dddSAndrii Nakryiko /* outputs */
52cb1c9dddSAndrii Nakryiko long total = 0;
53cb1c9dddSAndrii Nakryiko long dropped = 0;
54cb1c9dddSAndrii Nakryiko long skipped = 0;
55cb1c9dddSAndrii Nakryiko
56cb1c9dddSAndrii Nakryiko SEC("tp/syscalls/sys_enter_getpgid")
test_ringbuf(void * ctx)57cb1c9dddSAndrii Nakryiko int test_ringbuf(void *ctx)
58cb1c9dddSAndrii Nakryiko {
59cb1c9dddSAndrii Nakryiko int cur_pid = bpf_get_current_pid_tgid() >> 32;
60cb1c9dddSAndrii Nakryiko struct sample *sample;
61cb1c9dddSAndrii Nakryiko void *rb;
62cb1c9dddSAndrii Nakryiko
63cb1c9dddSAndrii Nakryiko if (cur_pid != pid)
64cb1c9dddSAndrii Nakryiko return 0;
65cb1c9dddSAndrii Nakryiko
66cb1c9dddSAndrii Nakryiko rb = bpf_map_lookup_elem(&ringbuf_arr, &target_ring);
67cb1c9dddSAndrii Nakryiko if (!rb) {
68cb1c9dddSAndrii Nakryiko skipped += 1;
69cb1c9dddSAndrii Nakryiko return 1;
70cb1c9dddSAndrii Nakryiko }
71cb1c9dddSAndrii Nakryiko
72cb1c9dddSAndrii Nakryiko sample = bpf_ringbuf_reserve(rb, sizeof(*sample), 0);
73cb1c9dddSAndrii Nakryiko if (!sample) {
74cb1c9dddSAndrii Nakryiko dropped += 1;
75cb1c9dddSAndrii Nakryiko return 1;
76cb1c9dddSAndrii Nakryiko }
77cb1c9dddSAndrii Nakryiko
78cb1c9dddSAndrii Nakryiko sample->pid = pid;
79cb1c9dddSAndrii Nakryiko bpf_get_current_comm(sample->comm, sizeof(sample->comm));
80cb1c9dddSAndrii Nakryiko sample->value = value;
81cb1c9dddSAndrii Nakryiko
82cb1c9dddSAndrii Nakryiko sample->seq = total;
83cb1c9dddSAndrii Nakryiko total += 1;
84cb1c9dddSAndrii Nakryiko
85cb1c9dddSAndrii Nakryiko bpf_ringbuf_submit(sample, 0);
86cb1c9dddSAndrii Nakryiko
87cb1c9dddSAndrii Nakryiko return 0;
88cb1c9dddSAndrii Nakryiko }
89