18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci// Copyright (c) 2020 Facebook
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include <linux/bpf.h>
58c2ecf20Sopenharmony_ci#include <bpf/bpf_helpers.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_cichar _license[] SEC("license") = "GPL";
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistruct sample {
108c2ecf20Sopenharmony_ci	int pid;
118c2ecf20Sopenharmony_ci	int seq;
128c2ecf20Sopenharmony_ci	long value;
138c2ecf20Sopenharmony_ci	char comm[16];
148c2ecf20Sopenharmony_ci};
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cistruct {
178c2ecf20Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_RINGBUF);
188c2ecf20Sopenharmony_ci	__uint(max_entries, 1 << 12);
198c2ecf20Sopenharmony_ci} ringbuf SEC(".maps");
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/* inputs */
228c2ecf20Sopenharmony_ciint pid = 0;
238c2ecf20Sopenharmony_cilong value = 0;
248c2ecf20Sopenharmony_cilong flags = 0;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* outputs */
278c2ecf20Sopenharmony_cilong total = 0;
288c2ecf20Sopenharmony_cilong discarded = 0;
298c2ecf20Sopenharmony_cilong dropped = 0;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cilong avail_data = 0;
328c2ecf20Sopenharmony_cilong ring_size = 0;
338c2ecf20Sopenharmony_cilong cons_pos = 0;
348c2ecf20Sopenharmony_cilong prod_pos = 0;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* inner state */
378c2ecf20Sopenharmony_cilong seq = 0;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciSEC("tp/syscalls/sys_enter_getpgid")
408c2ecf20Sopenharmony_ciint test_ringbuf(void *ctx)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	int cur_pid = bpf_get_current_pid_tgid() >> 32;
438c2ecf20Sopenharmony_ci	struct sample *sample;
448c2ecf20Sopenharmony_ci	int zero = 0;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	if (cur_pid != pid)
478c2ecf20Sopenharmony_ci		return 0;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	sample = bpf_ringbuf_reserve(&ringbuf, sizeof(*sample), 0);
508c2ecf20Sopenharmony_ci	if (!sample) {
518c2ecf20Sopenharmony_ci		__sync_fetch_and_add(&dropped, 1);
528c2ecf20Sopenharmony_ci		return 1;
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	sample->pid = pid;
568c2ecf20Sopenharmony_ci	bpf_get_current_comm(sample->comm, sizeof(sample->comm));
578c2ecf20Sopenharmony_ci	sample->value = value;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	sample->seq = seq++;
608c2ecf20Sopenharmony_ci	__sync_fetch_and_add(&total, 1);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	if (sample->seq & 1) {
638c2ecf20Sopenharmony_ci		/* copy from reserved sample to a new one... */
648c2ecf20Sopenharmony_ci		bpf_ringbuf_output(&ringbuf, sample, sizeof(*sample), flags);
658c2ecf20Sopenharmony_ci		/* ...and then discard reserved sample */
668c2ecf20Sopenharmony_ci		bpf_ringbuf_discard(sample, flags);
678c2ecf20Sopenharmony_ci		__sync_fetch_and_add(&discarded, 1);
688c2ecf20Sopenharmony_ci	} else {
698c2ecf20Sopenharmony_ci		bpf_ringbuf_submit(sample, flags);
708c2ecf20Sopenharmony_ci	}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	avail_data = bpf_ringbuf_query(&ringbuf, BPF_RB_AVAIL_DATA);
738c2ecf20Sopenharmony_ci	ring_size = bpf_ringbuf_query(&ringbuf, BPF_RB_RING_SIZE);
748c2ecf20Sopenharmony_ci	cons_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_CONS_POS);
758c2ecf20Sopenharmony_ci	prod_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_PROD_POS);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	return 0;
788c2ecf20Sopenharmony_ci}
79