// 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 (!ASSERT_OK_PTR(link, "attach_perf_event"))
		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 < 0) {
		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();
}
