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>
6*e91d280cSNaveen N. Rao #include "bpf_misc.h"
7cb1c9dddSAndrii Nakryiko 
8cb1c9dddSAndrii Nakryiko char _license[] SEC("license") = "GPL";
9cb1c9dddSAndrii Nakryiko 
10cb1c9dddSAndrii Nakryiko struct sample {
11cb1c9dddSAndrii Nakryiko 	int pid;
12cb1c9dddSAndrii Nakryiko 	int seq;
13cb1c9dddSAndrii Nakryiko 	long value;
14cb1c9dddSAndrii Nakryiko 	char comm[16];
15cb1c9dddSAndrii Nakryiko };
16cb1c9dddSAndrii Nakryiko 
17cb1c9dddSAndrii Nakryiko struct {
18cb1c9dddSAndrii Nakryiko 	__uint(type, BPF_MAP_TYPE_RINGBUF);
19cb1c9dddSAndrii Nakryiko } ringbuf SEC(".maps");
20cb1c9dddSAndrii Nakryiko 
21cb1c9dddSAndrii Nakryiko /* inputs */
22cb1c9dddSAndrii Nakryiko int pid = 0;
23cb1c9dddSAndrii Nakryiko long value = 0;
24cb1c9dddSAndrii Nakryiko long flags = 0;
25cb1c9dddSAndrii Nakryiko 
26cb1c9dddSAndrii Nakryiko /* outputs */
27cb1c9dddSAndrii Nakryiko long total = 0;
28cb1c9dddSAndrii Nakryiko long discarded = 0;
29cb1c9dddSAndrii Nakryiko long dropped = 0;
30cb1c9dddSAndrii Nakryiko 
31cb1c9dddSAndrii Nakryiko long avail_data = 0;
32cb1c9dddSAndrii Nakryiko long ring_size = 0;
33cb1c9dddSAndrii Nakryiko long cons_pos = 0;
34cb1c9dddSAndrii Nakryiko long prod_pos = 0;
35cb1c9dddSAndrii Nakryiko 
36cb1c9dddSAndrii Nakryiko /* inner state */
37cb1c9dddSAndrii Nakryiko long seq = 0;
38cb1c9dddSAndrii Nakryiko 
39*e91d280cSNaveen N. Rao SEC("fentry/" SYS_PREFIX "sys_getpgid")
test_ringbuf(void * ctx)40cb1c9dddSAndrii Nakryiko int test_ringbuf(void *ctx)
41cb1c9dddSAndrii Nakryiko {
42cb1c9dddSAndrii Nakryiko 	int cur_pid = bpf_get_current_pid_tgid() >> 32;
43cb1c9dddSAndrii Nakryiko 	struct sample *sample;
44cb1c9dddSAndrii Nakryiko 
45cb1c9dddSAndrii Nakryiko 	if (cur_pid != pid)
46cb1c9dddSAndrii Nakryiko 		return 0;
47cb1c9dddSAndrii Nakryiko 
48cb1c9dddSAndrii Nakryiko 	sample = bpf_ringbuf_reserve(&ringbuf, sizeof(*sample), 0);
49cb1c9dddSAndrii Nakryiko 	if (!sample) {
50cb1c9dddSAndrii Nakryiko 		__sync_fetch_and_add(&dropped, 1);
514d1b6298SAlexei Starovoitov 		return 0;
52cb1c9dddSAndrii Nakryiko 	}
53cb1c9dddSAndrii Nakryiko 
54cb1c9dddSAndrii Nakryiko 	sample->pid = pid;
55cb1c9dddSAndrii Nakryiko 	bpf_get_current_comm(sample->comm, sizeof(sample->comm));
56cb1c9dddSAndrii Nakryiko 	sample->value = value;
57cb1c9dddSAndrii Nakryiko 
58cb1c9dddSAndrii Nakryiko 	sample->seq = seq++;
59cb1c9dddSAndrii Nakryiko 	__sync_fetch_and_add(&total, 1);
60cb1c9dddSAndrii Nakryiko 
61cb1c9dddSAndrii Nakryiko 	if (sample->seq & 1) {
62cb1c9dddSAndrii Nakryiko 		/* copy from reserved sample to a new one... */
63cb1c9dddSAndrii Nakryiko 		bpf_ringbuf_output(&ringbuf, sample, sizeof(*sample), flags);
64cb1c9dddSAndrii Nakryiko 		/* ...and then discard reserved sample */
65cb1c9dddSAndrii Nakryiko 		bpf_ringbuf_discard(sample, flags);
66cb1c9dddSAndrii Nakryiko 		__sync_fetch_and_add(&discarded, 1);
67cb1c9dddSAndrii Nakryiko 	} else {
68cb1c9dddSAndrii Nakryiko 		bpf_ringbuf_submit(sample, flags);
69cb1c9dddSAndrii Nakryiko 	}
70cb1c9dddSAndrii Nakryiko 
71cb1c9dddSAndrii Nakryiko 	avail_data = bpf_ringbuf_query(&ringbuf, BPF_RB_AVAIL_DATA);
72cb1c9dddSAndrii Nakryiko 	ring_size = bpf_ringbuf_query(&ringbuf, BPF_RB_RING_SIZE);
73cb1c9dddSAndrii Nakryiko 	cons_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_CONS_POS);
74cb1c9dddSAndrii Nakryiko 	prod_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_PROD_POS);
75cb1c9dddSAndrii Nakryiko 
76cb1c9dddSAndrii Nakryiko 	return 0;
77cb1c9dddSAndrii Nakryiko }
78