// SPDX-License-Identifier: GPL-2.0
#include <linux/time64.h>

#include <bpf/bpf.h>
#include <bpf/btf.h>
#include <internal/xyarray.h>

#include "bpf_counter.h"
#include "bpf_skel/off_cpu.skel.h"
#include "cgroup.h"
#include "cpumap.h"
#include "debug.h"
#include "evlist.h"
#include "evsel.h"
#include "off_cpu.h"
#include "parse-events.h"
#include "perf-hooks.h"
#include "record.h"
#include "session.h"
#include "strlist.h"
#include "target.h"
#include "thread_map.h"

#define MAX_STACKS  32
#define MAX_PROC  4096
/* we don't need actual timestamp, just want to put the samples at last */
#define OFF_CPU_TIMESTAMP  (~0ull << 32)

static struct off_cpu_bpf *skel;

struct off_cpu_key {
	u32 pid;
	u32 tgid;
	u32 stack_id;
	u32 state;
	u64 cgroup_id;
};

union off_cpu_data {
	struct perf_event_header hdr;
	u64 array[1024 / sizeof(u64)];
};

static u64 off_cpu_raw[MAX_STACKS + 5];

static int off_cpu_config(struct evlist *evlist)
{
	char off_cpu_event[64];
	struct evsel *evsel;

	scnprintf(off_cpu_event, sizeof(off_cpu_event), "bpf-output/name=%s/", OFFCPU_EVENT);
	if (parse_event(evlist, off_cpu_event)) {
		pr_err("Failed to open off-cpu event\n");
		return -1;
	}

	evlist__for_each_entry(evlist, evsel) {
		if (evsel__is_offcpu_event(evsel)) {
			evsel->core.system_wide = true;
			break;
		}
	}

	return 0;
}

static void off_cpu_start(void *arg)
{
	struct evlist *evlist = arg;
	struct evsel *evsel;
	struct perf_cpu pcpu;
	unsigned int i;

	/* update task filter for the given workload */
	if (skel->rodata->has_task && skel->rodata->uses_tgid &&
	    perf_thread_map__pid(evlist__core(evlist)->threads, 0) != -1) {
		int fd;
		u32 pid;
		u8 val = 1;

		fd = bpf_map__fd(skel->maps.task_filter);
		pid = perf_thread_map__pid(evlist__core(evlist)->threads, 0);
		bpf_map_update_elem(fd, &pid, &val, BPF_ANY);
	}

	/* update BPF perf_event map */
	evsel = evlist__find_evsel_by_str(evlist, OFFCPU_EVENT);
	if (evsel == NULL) {
		pr_err("%s evsel not found\n", OFFCPU_EVENT);
		return;
	}

	perf_cpu_map__for_each_cpu(pcpu, i, evsel->core.cpus) {
		int err;
		int cpu_nr = pcpu.cpu;

		err = bpf_map__update_elem(skel->maps.offcpu_output, &cpu_nr, sizeof(int),
					   xyarray__entry(evsel->core.fd, cpu_nr, 0),
					   sizeof(int), BPF_ANY);
		if (err) {
			pr_err("Failed to update perf event map for direct off-cpu dumping\n");
			return;
		}
	}

	skel->bss->enabled = 1;
}

static void off_cpu_finish(void *arg __maybe_unused)
{
	skel->bss->enabled = 0;
	off_cpu_bpf__destroy(skel);
}

/* v5.18 kernel added prev_state arg, so it needs to check the signature */
static void check_sched_switch_args(void)
{
	struct btf *btf = btf__load_vmlinux_btf();
	const struct btf_type *t1, *t2, *t3;
	u32 type_id;

	if (!btf) {
		pr_debug("Missing btf, check if CONFIG_DEBUG_INFO_BTF is enabled\n");
		goto cleanup;
	}

	type_id = btf__find_by_name_kind(btf, "btf_trace_sched_switch",
					 BTF_KIND_TYPEDEF);
	if ((s32)type_id < 0)
		goto cleanup;

	t1 = btf__type_by_id(btf, type_id);
	if (t1 == NULL)
		goto cleanup;

	t2 = btf__type_by_id(btf, t1->type);
	if (t2 == NULL || !btf_is_ptr(t2))
		goto cleanup;

	t3 = btf__type_by_id(btf, t2->type);
	/* btf_trace func proto has one more argument for the context */
	if (t3 && btf_is_func_proto(t3) && btf_vlen(t3) == 5) {
		/* new format: pass prev_state as 4th arg */
		skel->rodata->has_prev_state = true;
	}
cleanup:
	btf__free(btf);
}

int off_cpu_prepare(struct evlist *evlist, struct target *target,
		    struct record_opts *opts)
{
	int err, fd, i;
	int ncpus = 1, ntasks = 1, ncgrps = 1;
	struct strlist *pid_slist = NULL;
	struct str_node *pos;

	if (off_cpu_config(evlist) < 0) {
		pr_err("Failed to config off-cpu BPF event\n");
		return -1;
	}

	skel = off_cpu_bpf__open();
	if (!skel) {
		pr_err("Failed to open off-cpu BPF skeleton\n");
		return -1;
	}

	/* don't need to set cpu filter for system-wide mode */
	if (target->cpu_list) {
		ncpus = perf_cpu_map__nr(evlist__core(evlist)->user_requested_cpus);
		bpf_map__set_max_entries(skel->maps.cpu_filter, ncpus);
		skel->rodata->has_cpu = 1;
	}

	if (target->pid) {
		pid_slist = strlist__new(target->pid, NULL);
		if (!pid_slist) {
			pr_err("Failed to create a strlist for pid\n");
			return -1;
		}

		ntasks = 0;
		strlist__for_each_entry(pos, pid_slist) {
			char *end_ptr;
			int pid = strtol(pos->s, &end_ptr, 10);

			if (pid == INT_MIN || pid == INT_MAX ||
			    (*end_ptr != '\0' && *end_ptr != ','))
				continue;

			ntasks++;
		}

		if (ntasks < MAX_PROC)
			ntasks = MAX_PROC;

		bpf_map__set_max_entries(skel->maps.task_filter, ntasks);
		skel->rodata->has_task = 1;
		skel->rodata->uses_tgid = 1;
	} else if (target__has_task(target)) {
		ntasks = perf_thread_map__nr(evlist__core(evlist)->threads);
		bpf_map__set_max_entries(skel->maps.task_filter, ntasks);
		skel->rodata->has_task = 1;
	} else if (target__none(target)) {
		bpf_map__set_max_entries(skel->maps.task_filter, MAX_PROC);
		skel->rodata->has_task = 1;
		skel->rodata->uses_tgid = 1;
	}

	if (evlist__first(evlist)->cgrp) {
		ncgrps = evlist__nr_entries(evlist) - 1; /* excluding a dummy */
		bpf_map__set_max_entries(skel->maps.cgroup_filter, ncgrps);

		if (!cgroup_is_v2("perf_event"))
			skel->rodata->uses_cgroup_v1 = true;
		skel->rodata->has_cgroup = 1;
	}

	if (opts->record_cgroup) {
		skel->rodata->needs_cgroup = true;

		if (!cgroup_is_v2("perf_event"))
			skel->rodata->uses_cgroup_v1 = true;
	}

	set_max_rlimit();
	check_sched_switch_args();

	err = off_cpu_bpf__load(skel);
	if (err) {
		pr_err("Failed to load off-cpu skeleton\n");
		goto out;
	}

	if (target->cpu_list) {
		u32 cpu;
		u8 val = 1;

		fd = bpf_map__fd(skel->maps.cpu_filter);

		for (i = 0; i < ncpus; i++) {
			cpu = perf_cpu_map__cpu(evlist__core(evlist)->user_requested_cpus, i).cpu;
			bpf_map_update_elem(fd, &cpu, &val, BPF_ANY);
		}
	}

	if (target->pid) {
		u8 val = 1;

		fd = bpf_map__fd(skel->maps.task_filter);

		strlist__for_each_entry(pos, pid_slist) {
			char *end_ptr;
			u32 tgid;
			int pid = strtol(pos->s, &end_ptr, 10);

			if (pid == INT_MIN || pid == INT_MAX ||
			    (*end_ptr != '\0' && *end_ptr != ','))
				continue;

			tgid = pid;
			bpf_map_update_elem(fd, &tgid, &val, BPF_ANY);
		}
	} else if (target__has_task(target)) {
		u32 pid;
		u8 val = 1;

		fd = bpf_map__fd(skel->maps.task_filter);

		for (i = 0; i < ntasks; i++) {
			pid = perf_thread_map__pid(evlist__core(evlist)->threads, i);
			bpf_map_update_elem(fd, &pid, &val, BPF_ANY);
		}
	}

	if (evlist__first(evlist)->cgrp) {
		struct evsel *evsel;
		u8 val = 1;

		fd = bpf_map__fd(skel->maps.cgroup_filter);

		evlist__for_each_entry(evlist, evsel) {
			struct cgroup *cgrp = evsel->cgrp;

			if (cgrp == NULL)
				continue;

			if (!cgrp->id && read_cgroup_id(cgrp) < 0) {
				pr_err("Failed to read cgroup id of %s\n",
				       cgrp->name);
				goto out;
			}

			bpf_map_update_elem(fd, &cgrp->id, &val, BPF_ANY);
		}
	}

	skel->bss->offcpu_thresh_ns = opts->off_cpu_thresh_ns;

	err = off_cpu_bpf__attach(skel);
	if (err) {
		pr_err("Failed to attach off-cpu BPF skeleton\n");
		goto out;
	}

	if (perf_hooks__set_hook("record_start", off_cpu_start, evlist) ||
	    perf_hooks__set_hook("record_end", off_cpu_finish, evlist)) {
		pr_err("Failed to attach off-cpu skeleton\n");
		goto out;
	}

	return 0;

out:
	off_cpu_bpf__destroy(skel);
	return -1;
}

int off_cpu_write(struct perf_session *session)
{
	int bytes = 0, size;
	int fd, stack;
	u32 raw_size;
	u64 sample_type, val, sid = 0;
	struct evsel *evsel;
	struct perf_data_file *file = &session->data->file;
	struct off_cpu_key prev, key;
	union off_cpu_data data = {
		.hdr = {
			.type = PERF_RECORD_SAMPLE,
			.misc = PERF_RECORD_MISC_USER,
		},
	};
	u64 tstamp = OFF_CPU_TIMESTAMP;

	skel->bss->enabled = 0;

	evsel = evlist__find_evsel_by_str(session->evlist, OFFCPU_EVENT);
	if (evsel == NULL) {
		pr_err("%s evsel not found\n", OFFCPU_EVENT);
		return 0;
	}

	sample_type = evsel->core.attr.sample_type;

	if (sample_type & ~OFFCPU_SAMPLE_TYPES) {
		pr_err("not supported sample type: %llx\n",
		       (unsigned long long)sample_type);
		return -1;
	}

	if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) {
		if (evsel->core.id)
			sid = evsel->core.id[0];
	}

	fd = bpf_map__fd(skel->maps.off_cpu);
	stack = bpf_map__fd(skel->maps.stacks);
	memset(&prev, 0, sizeof(prev));

	while (!bpf_map_get_next_key(fd, &prev, &key)) {
		int n = 1;  /* start from perf_event_header */

		bpf_map_lookup_elem(fd, &key, &val);

		/* zero-fill some of the fields, will be overwritten by raw_data when parsing */
		if (sample_type & PERF_SAMPLE_IDENTIFIER)
			data.array[n++] = sid;
		if (sample_type & PERF_SAMPLE_IP)
			data.array[n++] = 0;  /* will be updated */
		if (sample_type & PERF_SAMPLE_TID)
			data.array[n++] = 0;
		if (sample_type & PERF_SAMPLE_TIME)
			data.array[n++] = tstamp;
		if (sample_type & PERF_SAMPLE_CPU)
			data.array[n++] = 0;
		if (sample_type & PERF_SAMPLE_PERIOD)
			data.array[n++] = 0;
		if (sample_type & PERF_SAMPLE_RAW) {
			/*
			 *  [ size ][ data ]
			 *  [     data     ]
			 *  [     data     ]
			 *  [     data     ]
			 *  [ data ][ empty]
			 */
			int len = 0, i = 0;
			void *raw_data = (void *)data.array + n * sizeof(u64);

			off_cpu_raw[i++] = (u64)key.pid << 32 | key.tgid;
			off_cpu_raw[i++] = val;

			/* off_cpu_raw[i] is callchain->nr (updated later) */
			off_cpu_raw[i + 1] = PERF_CONTEXT_USER;
			off_cpu_raw[i + 2] = 0;

			bpf_map_lookup_elem(stack, &key.stack_id, &off_cpu_raw[i + 2]);
			while (off_cpu_raw[i + 2 + len])
				len++;

			off_cpu_raw[i] = len + 1;
			i += len + 2;

			off_cpu_raw[i++] = key.cgroup_id;

			raw_size = i * sizeof(u64) + sizeof(u32); /* 4 bytes for alignment */
			memcpy(raw_data, &raw_size, sizeof(raw_size));
			memcpy(raw_data + sizeof(u32), off_cpu_raw, i * sizeof(u64));

			n += i + 1;
		}
		if (sample_type & PERF_SAMPLE_CGROUP)
			data.array[n++] = key.cgroup_id;

		size = n * sizeof(u64);
		data.hdr.size = size;
		bytes += size;

		if (perf_data_file__write(file, &data, size) < 0) {
			pr_err("failed to write perf data, error: %m\n");
			return bytes;
		}

		prev = key;
		/* increase dummy timestamp to sort later samples */
		tstamp++;
	}
	return bytes;
}
