// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <pthread.h>
#include <sched.h>
#include <sys/socket.h>
#include <test_progs.h>
#include "bpf/libbpf_internal.h"
#include "test_perf_branches.skel.h"

static void check_good_sample(struct test_perf_branches *skel)
{
	int written_global = skel->bss->written_global_out;
	int required_size = skel->bss->required_size_out;
	int written_stack = skel->bss->written_stack_out;
	int pbe_size = sizeof(struct perf_branch_entry);
	int duration = 0;

	if (CHECK(!skel->bss->valid, "output not valid",
		 "no valid sample from prog"))
		return;

	/*
	 * It's hard to validate the contents of the branch entries b/c it
	 * would require some kind of disassembler and also encoding the
	 * valid jump instructions for supported architectures. So just check
	 * the easy stuff for now.
	 */
	CHECK(required_size <= 0, "read_branches_size", "err %d\n", required_size);
	CHECK(written_stack < 0, "read_branches_stack", "err %d\n", written_stack);
	CHECK(written_stack % pbe_size != 0, "read_branches_stack",
	      "stack bytes written=%d not multiple of struct size=%d\n",
	      written_stack, pbe_size);
	CHECK(written_global < 0, "read_branches_global", "err %d\n", written_global);
	CHECK(written_global % pbe_size != 0, "read_branches_global",
	      "global bytes written=%d not multiple of struct size=%d\n",
	      written_global, pbe_size);
	CHECK(written_global < written_stack, "read_branches_size",
	      "written_global=%d < written_stack=%d\n", written_global, written_stack);
}

static void check_bad_sample(struct test_perf_branches *skel)
{
	int written_global = skel->bss->written_global_out;
	int required_size = skel->bss->required_size_out;
	int written_stack = skel->bss->written_stack_out;
	int duration = 0;

	if (CHECK(!skel->bss->valid, "output not valid",
		 "no valid sample from prog"))
		return;

	CHECK((required_size != -EINVAL && required_size != -ENOENT),
	      "read_branches_size", "err %d\n", required_size);
	CHECK((written_stack != -EINVAL && written_stack != -ENOENT),
	      "read_branches_stack", "written %d\n", written_stack);
	CHECK((written_global != -EINVAL && written_global != -ENOENT),
	      "read_branches_global", "written %d\n", written_global);
}

static void test_perf_branches_common(int perf_fd,
				      void (*cb)(struct test_perf_branches *))
{
	struct test_perf_branches *skel;
	int err, i, duration = 0;
	bool detached = false;
	struct bpf_link *link;
	volatile int j = 0;
	cpu_set_t cpu_set;

	skel = test_perf_branches__open_and_load();
	if (CHECK(!skel, "test_perf_branches_load",
		  "perf_branches skeleton failed\n"))
		return;

	/* attach perf_event */
	link = bpf_program__attach_perf_event(skel->progs.perf_branches, perf_fd);
	if (CHECK(IS_ERR(link), "attach_perf_event", "err %ld\n", PTR_ERR(link)))
		goto out_destroy_skel;

	/* generate some branches on cpu 0 */
	CPU_ZERO(&cpu_set);
	CPU_SET(0, &cpu_set);
	err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
	if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err))
		goto out_destroy;
	/* spin the loop for a while (random high number) */
	for (i = 0; i < 1000000; ++i)
		++j;

	test_perf_branches__detach(skel);
	detached = true;

	cb(skel);
out_destroy:
	bpf_link__destroy(link);
out_destroy_skel:
	if (!detached)
		test_perf_branches__detach(skel);
	test_perf_branches__destroy(skel);
}

static void test_perf_branches_hw(void)
{
	struct perf_event_attr attr = {0};
	int duration = 0;
	int pfd;

	/* create perf event */
	attr.size = sizeof(attr);
	attr.type = PERF_TYPE_HARDWARE;
	attr.config = PERF_COUNT_HW_CPU_CYCLES;
	attr.freq = 1;
	attr.sample_freq = 4000;
	attr.sample_type = PERF_SAMPLE_BRANCH_STACK;
	attr.branch_sample_type = PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_ANY;
	pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);

	/*
	 * Some setups don't support branch records (virtual machines, !x86),
	 * so skip test in this case.
	 */
	if (pfd == -1) {
		if (errno == ENOENT || errno == EOPNOTSUPP) {
			printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n",
			       __func__);
			test__skip();
			return;
		}
		if (CHECK(pfd < 0, "perf_event_open", "err %d errno %d\n",
			  pfd, errno))
			return;
	}

	test_perf_branches_common(pfd, check_good_sample);

	close(pfd);
}

/*
 * Tests negative case -- run bpf_read_branch_records() on improperly configured
 * perf event.
 */
static void test_perf_branches_no_hw(void)
{
	struct perf_event_attr attr = {0};
	int duration = 0;
	int pfd;

	/* create perf event */
	attr.size = sizeof(attr);
	attr.type = PERF_TYPE_SOFTWARE;
	attr.config = PERF_COUNT_SW_CPU_CLOCK;
	attr.freq = 1;
	attr.sample_freq = 4000;
	pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);
	if (CHECK(pfd < 0, "perf_event_open", "err %d\n", pfd))
		return;

	test_perf_branches_common(pfd, check_bad_sample);

	close(pfd);
}

void test_perf_branches(void)
{
	if (test__start_subtest("perf_branches_hw"))
		test_perf_branches_hw();
	if (test__start_subtest("perf_branches_no_hw"))
		test_perf_branches_no_hw();
}
