// SPDX-License-Identifier: GPL-2.0
#ifdef HAVE_BPF_SKEL
#define _GNU_SOURCE
#include "timerlat.h"
#include "timerlat_bpf.h"
#include "timerlat.skel.h"

static struct timerlat_bpf *bpf;

/* BPF object and program for action program */
static struct bpf_object *obj;
static struct bpf_program *prog;

/*
 * timerlat_bpf_init - load and initialize BPF program to collect timerlat data
 */
int timerlat_bpf_init(struct timerlat_params *params)
{
	int err;

	debug_msg("Loading BPF program\n");

	bpf = timerlat_bpf__open();
	if (!bpf)
		return 1;

	/* Pass common options */
	bpf->rodata->output_divisor = params->common.output_divisor;
	bpf->rodata->entries = params->common.hist.entries;
	bpf->rodata->irq_threshold = params->common.stop_us;
	bpf->rodata->thread_threshold = params->common.stop_total_us;
	bpf->rodata->aa_only = params->common.aa_only;

	if (params->common.hist.entries != 0) {
		/* Pass histogram options */
		bpf->rodata->bucket_size = params->common.hist.bucket_size;

		/* Set histogram array sizes */
		bpf_map__set_max_entries(bpf->maps.hist_irq, params->common.hist.entries);
		bpf_map__set_max_entries(bpf->maps.hist_thread, params->common.hist.entries);
		bpf_map__set_max_entries(bpf->maps.hist_user, params->common.hist.entries);
	} else {
		/* No entries, disable histogram */
		bpf_map__set_autocreate(bpf->maps.hist_irq, false);
		bpf_map__set_autocreate(bpf->maps.hist_thread, false);
		bpf_map__set_autocreate(bpf->maps.hist_user, false);
	}

	if (params->common.aa_only) {
		/* Auto-analysis only, disable summary */
		bpf_map__set_autocreate(bpf->maps.summary_irq, false);
		bpf_map__set_autocreate(bpf->maps.summary_thread, false);
		bpf_map__set_autocreate(bpf->maps.summary_user, false);
	}

	/* Load and verify BPF program */
	err = timerlat_bpf__load(bpf);
	if (err) {
		timerlat_bpf__destroy(bpf);
		return err;
	}

	return 0;
}

/*
 * timerlat_bpf_set_action - set action on threshold executed on BPF side
 */
static int timerlat_bpf_set_action(struct bpf_program *prog)
{
	unsigned int key = 0, value = bpf_program__fd(prog);

	return bpf_map__update_elem(bpf->maps.bpf_action,
				    &key, sizeof(key),
				    &value, sizeof(value),
				    BPF_ANY);
}

/*
 * timerlat_bpf_attach - attach BPF program to collect timerlat data
 */
int timerlat_bpf_attach(void)
{
	debug_msg("Attaching BPF program\n");

	return timerlat_bpf__attach(bpf);
}

/*
 * timerlat_bpf_detach - detach BPF program to collect timerlat data
 */
void timerlat_bpf_detach(void)
{
	timerlat_bpf__detach(bpf);
}

/*
 * timerlat_bpf_detach - destroy BPF program to collect timerlat data
 */
void timerlat_bpf_destroy(void)
{
	timerlat_bpf__destroy(bpf);
	bpf = NULL;
	if (obj)
		bpf_object__close(obj);
	obj = NULL;
	prog = NULL;
}

static int handle_rb_event(void *ctx, void *data, size_t data_sz)
{
	return 0;
}

/*
 * timerlat_bpf_wait - wait until tracing is stopped or signal
 */
int timerlat_bpf_wait(int timeout)
{
	struct ring_buffer *rb;
	int retval;

	rb = ring_buffer__new(bpf_map__fd(bpf->maps.signal_stop_tracing),
			      handle_rb_event, NULL, NULL);
	retval = ring_buffer__poll(rb, timeout * 1000);
	ring_buffer__free(rb);

	return retval;
}

/*
 * timerlat_bpf_restart_tracing - restart stopped tracing
 */
int timerlat_bpf_restart_tracing(void)
{
	unsigned int key = 0;
	unsigned long long value = 0;

	return bpf_map__update_elem(bpf->maps.stop_tracing,
				    &key, sizeof(key),
				    &value, sizeof(value), BPF_ANY);
}

static int get_value(struct bpf_map *map_irq,
		     struct bpf_map *map_thread,
		     struct bpf_map *map_user,
		     int key,
		     long long *value_irq,
		     long long *value_thread,
		     long long *value_user)
{
	int err;

	err = bpf_map__lookup_elem(map_irq, &key,
				   sizeof(unsigned int), value_irq,
				   sizeof(long long) * nr_cpus, 0);
	if (err)
		return err;
	err = bpf_map__lookup_elem(map_thread, &key,
				   sizeof(unsigned int), value_thread,
				   sizeof(long long) * nr_cpus, 0);
	if (err)
		return err;
	err = bpf_map__lookup_elem(map_user, &key,
				   sizeof(unsigned int), value_user,
				   sizeof(long long) * nr_cpus, 0);
	if (err)
		return err;
	return 0;
}

/*
 * timerlat_bpf_get_hist_value - get value from BPF hist map
 */
int timerlat_bpf_get_hist_value(int key,
				long long *value_irq,
				long long *value_thread,
				long long *value_user)
{
	return get_value(bpf->maps.hist_irq,
			 bpf->maps.hist_thread,
			 bpf->maps.hist_user,
			 key, value_irq, value_thread, value_user);
}

/*
 * timerlat_bpf_get_summary_value - get value from BPF summary map
 */
int timerlat_bpf_get_summary_value(enum summary_field key,
				   long long *value_irq,
				   long long *value_thread,
				   long long *value_user)
{
	return get_value(bpf->maps.summary_irq,
			 bpf->maps.summary_thread,
			 bpf->maps.summary_user,
			 key, value_irq, value_thread, value_user);
}

/*
 * timerlat_load_bpf_action_program - load and register a BPF action program
 */
int timerlat_load_bpf_action_program(const char *program_path)
{
	int err;

	obj = bpf_object__open_file(program_path, NULL);
	if (!obj) {
		err_msg("Failed to open BPF action program: %s\n", program_path);
		goto out_err;
	}

	err = bpf_object__load(obj);
	if (err) {
		err_msg("Failed to load BPF action program: %s\n", program_path);
		goto out_obj_err;
	}

	prog = bpf_object__find_program_by_name(obj, "action_handler");
	if (!prog) {
		err_msg("BPF action program must have 'action_handler' function: %s\n",
			program_path);
		goto out_obj_err;
	}

	err = timerlat_bpf_set_action(prog);
	if (err) {
		err_msg("Failed to register BPF action program: %s\n", program_path);
		goto out_prog_err;
	}

	return 0;

out_prog_err:
	prog = NULL;
out_obj_err:
	bpf_object__close(obj);
	obj = NULL;
out_err:
	return 1;
}

#endif /* HAVE_BPF_SKEL */
