// SPDX-License-Identifier: GPL-2.0

/* Copyright (c) 2019 Facebook */

#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <linux/err.h>
#include <linux/zalloc.h>
#include <bpf/bpf.h>
#include <bpf/btf.h>
#include <bpf/libbpf.h>
#include <api/fs/fs.h>
#include <perf/bpf_perf.h>

#include "bpf_counter.h"
#include "counts.h"
#include "debug.h"
#include "evsel.h"
#include "evlist.h"
#include "target.h"
#include "cpumap.h"
#include "thread_map.h"

#include "bpf_skel/bpf_prog_profiler.skel.h"
#include "bpf_skel/bperf_u.h"
#include "bpf_skel/bperf_leader.skel.h"
#include "bpf_skel/bperf_follower.skel.h"

#define ATTR_MAP_SIZE 16

static inline void *u64_to_ptr(__u64 ptr)
{
	return (void *)(unsigned long)ptr;
}

static void set_max_rlimit(void)
{
	struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };

	setrlimit(RLIMIT_MEMLOCK, &rinf);
}

static struct bpf_counter *bpf_counter_alloc(void)
{
	struct bpf_counter *counter;

	counter = zalloc(sizeof(*counter));
	if (counter)
		INIT_LIST_HEAD(&counter->list);
	return counter;
}

static int bpf_program_profiler__destroy(struct evsel *evsel)
{
	struct bpf_counter *counter, *tmp;

	list_for_each_entry_safe(counter, tmp,
				 &evsel->bpf_counter_list, list) {
		list_del_init(&counter->list);
		bpf_prog_profiler_bpf__destroy(counter->skel);
		free(counter);
	}
	assert(list_empty(&evsel->bpf_counter_list));

	return 0;
}

static char *bpf_target_prog_name(int tgt_fd)
{
	struct bpf_prog_info_linear *info_linear;
	struct bpf_func_info *func_info;
	const struct btf_type *t;
	char *name = NULL;
	struct btf *btf;

	info_linear = bpf_program__get_prog_info_linear(
		tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO);
	if (IS_ERR_OR_NULL(info_linear)) {
		pr_debug("failed to get info_linear for prog FD %d\n", tgt_fd);
		return NULL;
	}

	if (info_linear->info.btf_id == 0 ||
	    btf__get_from_id(info_linear->info.btf_id, &btf)) {
		pr_debug("prog FD %d doesn't have valid btf\n", tgt_fd);
		goto out;
	}

	func_info = u64_to_ptr(info_linear->info.func_info);
	t = btf__type_by_id(btf, func_info[0].type_id);
	if (!t) {
		pr_debug("btf %d doesn't have type %d\n",
			 info_linear->info.btf_id, func_info[0].type_id);
		goto out;
	}
	name = strdup(btf__name_by_offset(btf, t->name_off));
out:
	free(info_linear);
	return name;
}

static int bpf_program_profiler_load_one(struct evsel *evsel, u32 prog_id)
{
	struct bpf_prog_profiler_bpf *skel;
	struct bpf_counter *counter;
	struct bpf_program *prog;
	char *prog_name;
	int prog_fd;
	int err;

	prog_fd = bpf_prog_get_fd_by_id(prog_id);
	if (prog_fd < 0) {
		pr_err("Failed to open fd for bpf prog %u\n", prog_id);
		return -1;
	}
	counter = bpf_counter_alloc();
	if (!counter) {
		close(prog_fd);
		return -1;
	}

	skel = bpf_prog_profiler_bpf__open();
	if (!skel) {
		pr_err("Failed to open bpf skeleton\n");
		goto err_out;
	}

	skel->rodata->num_cpu = evsel__nr_cpus(evsel);

	bpf_map__resize(skel->maps.events, evsel__nr_cpus(evsel));
	bpf_map__resize(skel->maps.fentry_readings, 1);
	bpf_map__resize(skel->maps.accum_readings, 1);

	prog_name = bpf_target_prog_name(prog_fd);
	if (!prog_name) {
		pr_err("Failed to get program name for bpf prog %u. Does it have BTF?\n", prog_id);
		goto err_out;
	}

	bpf_object__for_each_program(prog, skel->obj) {
		err = bpf_program__set_attach_target(prog, prog_fd, prog_name);
		if (err) {
			pr_err("bpf_program__set_attach_target failed.\n"
			       "Does bpf prog %u have BTF?\n", prog_id);
			goto err_out;
		}
	}
	set_max_rlimit();
	err = bpf_prog_profiler_bpf__load(skel);
	if (err) {
		pr_err("bpf_prog_profiler_bpf__load failed\n");
		goto err_out;
	}

	assert(skel != NULL);
	counter->skel = skel;
	list_add(&counter->list, &evsel->bpf_counter_list);
	close(prog_fd);
	return 0;
err_out:
	bpf_prog_profiler_bpf__destroy(skel);
	free(counter);
	close(prog_fd);
	return -1;
}

static int bpf_program_profiler__load(struct evsel *evsel, struct target *target)
{
	char *bpf_str, *bpf_str_, *tok, *saveptr = NULL, *p;
	u32 prog_id;
	int ret;

	bpf_str_ = bpf_str = strdup(target->bpf_str);
	if (!bpf_str)
		return -1;

	while ((tok = strtok_r(bpf_str, ",", &saveptr)) != NULL) {
		prog_id = strtoul(tok, &p, 10);
		if (prog_id == 0 || prog_id == UINT_MAX ||
		    (*p != '\0' && *p != ',')) {
			pr_err("Failed to parse bpf prog ids %s\n",
			       target->bpf_str);
			return -1;
		}

		ret = bpf_program_profiler_load_one(evsel, prog_id);
		if (ret) {
			bpf_program_profiler__destroy(evsel);
			free(bpf_str_);
			return -1;
		}
		bpf_str = NULL;
	}
	free(bpf_str_);
	return 0;
}

static int bpf_program_profiler__enable(struct evsel *evsel)
{
	struct bpf_counter *counter;
	int ret;

	list_for_each_entry(counter, &evsel->bpf_counter_list, list) {
		assert(counter->skel != NULL);
		ret = bpf_prog_profiler_bpf__attach(counter->skel);
		if (ret) {
			bpf_program_profiler__destroy(evsel);
			return ret;
		}
	}
	return 0;
}

static int bpf_program_profiler__disable(struct evsel *evsel)
{
	struct bpf_counter *counter;

	list_for_each_entry(counter, &evsel->bpf_counter_list, list) {
		assert(counter->skel != NULL);
		bpf_prog_profiler_bpf__detach(counter->skel);
	}
	return 0;
}

static int bpf_program_profiler__read(struct evsel *evsel)
{
	// perf_cpu_map uses /sys/devices/system/cpu/online
	int num_cpu = evsel__nr_cpus(evsel);
	// BPF_MAP_TYPE_PERCPU_ARRAY uses /sys/devices/system/cpu/possible
	// Sometimes possible > online, like on a Ryzen 3900X that has 24
	// threads but its possible showed 0-31 -acme
	int num_cpu_bpf = libbpf_num_possible_cpus();
	struct bpf_perf_event_value values[num_cpu_bpf];
	struct bpf_counter *counter;
	int reading_map_fd;
	__u32 key = 0;
	int err, cpu;

	if (list_empty(&evsel->bpf_counter_list))
		return -EAGAIN;

	for (cpu = 0; cpu < num_cpu; cpu++) {
		perf_counts(evsel->counts, cpu, 0)->val = 0;
		perf_counts(evsel->counts, cpu, 0)->ena = 0;
		perf_counts(evsel->counts, cpu, 0)->run = 0;
	}
	list_for_each_entry(counter, &evsel->bpf_counter_list, list) {
		struct bpf_prog_profiler_bpf *skel = counter->skel;

		assert(skel != NULL);
		reading_map_fd = bpf_map__fd(skel->maps.accum_readings);

		err = bpf_map_lookup_elem(reading_map_fd, &key, values);
		if (err) {
			pr_err("failed to read value\n");
			return err;
		}

		for (cpu = 0; cpu < num_cpu; cpu++) {
			perf_counts(evsel->counts, cpu, 0)->val += values[cpu].counter;
			perf_counts(evsel->counts, cpu, 0)->ena += values[cpu].enabled;
			perf_counts(evsel->counts, cpu, 0)->run += values[cpu].running;
		}
	}
	return 0;
}

static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu,
					    int fd)
{
	struct bpf_prog_profiler_bpf *skel;
	struct bpf_counter *counter;
	int ret;

	list_for_each_entry(counter, &evsel->bpf_counter_list, list) {
		skel = counter->skel;
		assert(skel != NULL);

		ret = bpf_map_update_elem(bpf_map__fd(skel->maps.events),
					  &cpu, &fd, BPF_ANY);
		if (ret)
			return ret;
	}
	return 0;
}

struct bpf_counter_ops bpf_program_profiler_ops = {
	.load       = bpf_program_profiler__load,
	.enable	    = bpf_program_profiler__enable,
	.disable    = bpf_program_profiler__disable,
	.read       = bpf_program_profiler__read,
	.destroy    = bpf_program_profiler__destroy,
	.install_pe = bpf_program_profiler__install_pe,
};

static __u32 bpf_link_get_id(int fd)
{
	struct bpf_link_info link_info = {0};
	__u32 link_info_len = sizeof(link_info);

	bpf_obj_get_info_by_fd(fd, &link_info, &link_info_len);
	return link_info.id;
}

static __u32 bpf_link_get_prog_id(int fd)
{
	struct bpf_link_info link_info = {0};
	__u32 link_info_len = sizeof(link_info);

	bpf_obj_get_info_by_fd(fd, &link_info, &link_info_len);
	return link_info.prog_id;
}

static __u32 bpf_map_get_id(int fd)
{
	struct bpf_map_info map_info = {0};
	__u32 map_info_len = sizeof(map_info);

	bpf_obj_get_info_by_fd(fd, &map_info, &map_info_len);
	return map_info.id;
}

static bool bperf_attr_map_compatible(int attr_map_fd)
{
	struct bpf_map_info map_info = {0};
	__u32 map_info_len = sizeof(map_info);
	int err;

	err = bpf_obj_get_info_by_fd(attr_map_fd, &map_info, &map_info_len);

	if (err)
		return false;
	return (map_info.key_size == sizeof(struct perf_event_attr)) &&
		(map_info.value_size == sizeof(struct perf_event_attr_map_entry));
}

static int bperf_lock_attr_map(struct target *target)
{
	char path[PATH_MAX];
	int map_fd, err;

	if (target->attr_map) {
		scnprintf(path, PATH_MAX, "%s", target->attr_map);
	} else {
		scnprintf(path, PATH_MAX, "%s/fs/bpf/%s", sysfs__mountpoint(),
			  BPF_PERF_DEFAULT_ATTR_MAP_PATH);
	}

	if (access(path, F_OK)) {
		map_fd = bpf_create_map(BPF_MAP_TYPE_HASH,
					sizeof(struct perf_event_attr),
					sizeof(struct perf_event_attr_map_entry),
					ATTR_MAP_SIZE, 0);
		if (map_fd < 0)
			return -1;

		err = bpf_obj_pin(map_fd, path);
		if (err) {
			/* someone pinned the map in parallel? */
			close(map_fd);
			map_fd = bpf_obj_get(path);
			if (map_fd < 0)
				return -1;
		}
	} else {
		map_fd = bpf_obj_get(path);
		if (map_fd < 0)
			return -1;
	}

	if (!bperf_attr_map_compatible(map_fd)) {
		close(map_fd);
		return -1;

	}
	err = flock(map_fd, LOCK_EX);
	if (err) {
		close(map_fd);
		return -1;
	}
	return map_fd;
}

/* trigger the leader program on a cpu */
static int bperf_trigger_reading(int prog_fd, int cpu)
{
	DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
			    .ctx_in = NULL,
			    .ctx_size_in = 0,
			    .flags = BPF_F_TEST_RUN_ON_CPU,
			    .cpu = cpu,
			    .retval = 0,
		);

	return bpf_prog_test_run_opts(prog_fd, &opts);
}

static int bperf_check_target(struct evsel *evsel,
			      struct target *target,
			      enum bperf_filter_type *filter_type,
			      __u32 *filter_entry_cnt)
{
	if (evsel->leader->core.nr_members > 1) {
		pr_err("bpf managed perf events do not yet support groups.\n");
		return -1;
	}

	/* determine filter type based on target */
	if (target->system_wide) {
		*filter_type = BPERF_FILTER_GLOBAL;
		*filter_entry_cnt = 1;
	} else if (target->cpu_list) {
		*filter_type = BPERF_FILTER_CPU;
		*filter_entry_cnt = perf_cpu_map__nr(evsel__cpus(evsel));
	} else if (target->tid) {
		*filter_type = BPERF_FILTER_PID;
		*filter_entry_cnt = perf_thread_map__nr(evsel->core.threads);
	} else if (target->pid || evsel->evlist->workload.pid != -1) {
		*filter_type = BPERF_FILTER_TGID;
		*filter_entry_cnt = perf_thread_map__nr(evsel->core.threads);
	} else {
		pr_err("bpf managed perf events do not yet support these targets.\n");
		return -1;
	}

	return 0;
}

static	struct perf_cpu_map *all_cpu_map;

static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd,
				       struct perf_event_attr_map_entry *entry)
{
	struct bperf_leader_bpf *skel = bperf_leader_bpf__open();
	int link_fd, diff_map_fd, err;
	struct bpf_link *link = NULL;

	if (!skel) {
		pr_err("Failed to open leader skeleton\n");
		return -1;
	}

	bpf_map__resize(skel->maps.events, libbpf_num_possible_cpus());
	err = bperf_leader_bpf__load(skel);
	if (err) {
		pr_err("Failed to load leader skeleton\n");
		goto out;
	}

	link = bpf_program__attach(skel->progs.on_switch);
	if (IS_ERR(link)) {
		pr_err("Failed to attach leader program\n");
		err = PTR_ERR(link);
		goto out;
	}

	link_fd = bpf_link__fd(link);
	diff_map_fd = bpf_map__fd(skel->maps.diff_readings);
	entry->link_id = bpf_link_get_id(link_fd);
	entry->diff_map_id = bpf_map_get_id(diff_map_fd);
	err = bpf_map_update_elem(attr_map_fd, &evsel->core.attr, entry, BPF_ANY);
	assert(err == 0);

	evsel->bperf_leader_link_fd = bpf_link_get_fd_by_id(entry->link_id);
	assert(evsel->bperf_leader_link_fd >= 0);

	/*
	 * save leader_skel for install_pe, which is called within
	 * following evsel__open_per_cpu call
	 */
	evsel->leader_skel = skel;
	evsel__open_per_cpu(evsel, all_cpu_map, -1);

out:
	bperf_leader_bpf__destroy(skel);
	bpf_link__destroy(link);
	return err;
}

static int bperf__load(struct evsel *evsel, struct target *target)
{
	struct perf_event_attr_map_entry entry = {0xffffffff, 0xffffffff};
	int attr_map_fd, diff_map_fd = -1, err;
	enum bperf_filter_type filter_type;
	__u32 filter_entry_cnt, i;

	if (bperf_check_target(evsel, target, &filter_type, &filter_entry_cnt))
		return -1;

	if (!all_cpu_map) {
		all_cpu_map = perf_cpu_map__new(NULL);
		if (!all_cpu_map)
			return -1;
	}

	evsel->bperf_leader_prog_fd = -1;
	evsel->bperf_leader_link_fd = -1;

	/*
	 * Step 1: hold a fd on the leader program and the bpf_link, if
	 * the program is not already gone, reload the program.
	 * Use flock() to ensure exclusive access to the perf_event_attr
	 * map.
	 */
	attr_map_fd = bperf_lock_attr_map(target);
	if (attr_map_fd < 0) {
		pr_err("Failed to lock perf_event_attr map\n");
		return -1;
	}

	err = bpf_map_lookup_elem(attr_map_fd, &evsel->core.attr, &entry);
	if (err) {
		err = bpf_map_update_elem(attr_map_fd, &evsel->core.attr, &entry, BPF_ANY);
		if (err)
			goto out;
	}

	evsel->bperf_leader_link_fd = bpf_link_get_fd_by_id(entry.link_id);
	if (evsel->bperf_leader_link_fd < 0 &&
	    bperf_reload_leader_program(evsel, attr_map_fd, &entry))
		goto out;

	/*
	 * The bpf_link holds reference to the leader program, and the
	 * leader program holds reference to the maps. Therefore, if
	 * link_id is valid, diff_map_id should also be valid.
	 */
	evsel->bperf_leader_prog_fd = bpf_prog_get_fd_by_id(
		bpf_link_get_prog_id(evsel->bperf_leader_link_fd));
	assert(evsel->bperf_leader_prog_fd >= 0);

	diff_map_fd = bpf_map_get_fd_by_id(entry.diff_map_id);
	assert(diff_map_fd >= 0);

	/*
	 * bperf uses BPF_PROG_TEST_RUN to get accurate reading. Check
	 * whether the kernel support it
	 */
	err = bperf_trigger_reading(evsel->bperf_leader_prog_fd, 0);
	if (err) {
		pr_err("The kernel does not support test_run for raw_tp BPF programs.\n"
		       "Therefore, --use-bpf might show inaccurate readings\n");
		goto out;
	}

	/* Step 2: load the follower skeleton */
	evsel->follower_skel = bperf_follower_bpf__open();
	if (!evsel->follower_skel) {
		pr_err("Failed to open follower skeleton\n");
		goto out;
	}

	/* attach fexit program to the leader program */
	bpf_program__set_attach_target(evsel->follower_skel->progs.fexit_XXX,
				       evsel->bperf_leader_prog_fd, "on_switch");

	/* connect to leader diff_reading map */
	bpf_map__reuse_fd(evsel->follower_skel->maps.diff_readings, diff_map_fd);

	/* set up reading map */
	bpf_map__set_max_entries(evsel->follower_skel->maps.accum_readings,
				 filter_entry_cnt);
	/* set up follower filter based on target */
	bpf_map__set_max_entries(evsel->follower_skel->maps.filter,
				 filter_entry_cnt);
	err = bperf_follower_bpf__load(evsel->follower_skel);
	if (err) {
		pr_err("Failed to load follower skeleton\n");
		bperf_follower_bpf__destroy(evsel->follower_skel);
		evsel->follower_skel = NULL;
		goto out;
	}

	for (i = 0; i < filter_entry_cnt; i++) {
		int filter_map_fd;
		__u32 key;

		if (filter_type == BPERF_FILTER_PID ||
		    filter_type == BPERF_FILTER_TGID)
			key = evsel->core.threads->map[i].pid;
		else if (filter_type == BPERF_FILTER_CPU)
			key = evsel->core.cpus->map[i];
		else
			break;

		filter_map_fd = bpf_map__fd(evsel->follower_skel->maps.filter);
		bpf_map_update_elem(filter_map_fd, &key, &i, BPF_ANY);
	}

	evsel->follower_skel->bss->type = filter_type;

	err = bperf_follower_bpf__attach(evsel->follower_skel);

out:
	if (err && evsel->bperf_leader_link_fd >= 0)
		close(evsel->bperf_leader_link_fd);
	if (err && evsel->bperf_leader_prog_fd >= 0)
		close(evsel->bperf_leader_prog_fd);
	if (diff_map_fd >= 0)
		close(diff_map_fd);

	flock(attr_map_fd, LOCK_UN);
	close(attr_map_fd);

	return err;
}

static int bperf__install_pe(struct evsel *evsel, int cpu, int fd)
{
	struct bperf_leader_bpf *skel = evsel->leader_skel;

	return bpf_map_update_elem(bpf_map__fd(skel->maps.events),
				   &cpu, &fd, BPF_ANY);
}

/*
 * trigger the leader prog on each cpu, so the accum_reading map could get
 * the latest readings.
 */
static int bperf_sync_counters(struct evsel *evsel)
{
	int num_cpu, i, cpu;

	num_cpu = all_cpu_map->nr;
	for (i = 0; i < num_cpu; i++) {
		cpu = all_cpu_map->map[i];
		bperf_trigger_reading(evsel->bperf_leader_prog_fd, cpu);
	}
	return 0;
}

static int bperf__enable(struct evsel *evsel)
{
	evsel->follower_skel->bss->enabled = 1;
	return 0;
}

static int bperf__disable(struct evsel *evsel)
{
	evsel->follower_skel->bss->enabled = 0;
	return 0;
}

static int bperf__read(struct evsel *evsel)
{
	struct bperf_follower_bpf *skel = evsel->follower_skel;
	__u32 num_cpu_bpf = cpu__max_cpu();
	struct bpf_perf_event_value values[num_cpu_bpf];
	int reading_map_fd, err = 0;
	__u32 i, j, num_cpu;

	bperf_sync_counters(evsel);
	reading_map_fd = bpf_map__fd(skel->maps.accum_readings);

	for (i = 0; i < bpf_map__max_entries(skel->maps.accum_readings); i++) {
		__u32 cpu;

		err = bpf_map_lookup_elem(reading_map_fd, &i, values);
		if (err)
			goto out;
		switch (evsel->follower_skel->bss->type) {
		case BPERF_FILTER_GLOBAL:
			assert(i == 0);

			num_cpu = all_cpu_map->nr;
			for (j = 0; j < num_cpu; j++) {
				cpu = all_cpu_map->map[j];
				perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter;
				perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled;
				perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running;
			}
			break;
		case BPERF_FILTER_CPU:
			cpu = evsel->core.cpus->map[i];
			perf_counts(evsel->counts, i, 0)->val = values[cpu].counter;
			perf_counts(evsel->counts, i, 0)->ena = values[cpu].enabled;
			perf_counts(evsel->counts, i, 0)->run = values[cpu].running;
			break;
		case BPERF_FILTER_PID:
		case BPERF_FILTER_TGID:
			perf_counts(evsel->counts, 0, i)->val = 0;
			perf_counts(evsel->counts, 0, i)->ena = 0;
			perf_counts(evsel->counts, 0, i)->run = 0;

			for (cpu = 0; cpu < num_cpu_bpf; cpu++) {
				perf_counts(evsel->counts, 0, i)->val += values[cpu].counter;
				perf_counts(evsel->counts, 0, i)->ena += values[cpu].enabled;
				perf_counts(evsel->counts, 0, i)->run += values[cpu].running;
			}
			break;
		default:
			break;
		}
	}
out:
	return err;
}

static int bperf__destroy(struct evsel *evsel)
{
	bperf_follower_bpf__destroy(evsel->follower_skel);
	close(evsel->bperf_leader_prog_fd);
	close(evsel->bperf_leader_link_fd);
	return 0;
}

/*
 * bperf: share hardware PMCs with BPF
 *
 * perf uses performance monitoring counters (PMC) to monitor system
 * performance. The PMCs are limited hardware resources. For example,
 * Intel CPUs have 3x fixed PMCs and 4x programmable PMCs per cpu.
 *
 * Modern data center systems use these PMCs in many different ways:
 * system level monitoring, (maybe nested) container level monitoring, per
 * process monitoring, profiling (in sample mode), etc. In some cases,
 * there are more active perf_events than available hardware PMCs. To allow
 * all perf_events to have a chance to run, it is necessary to do expensive
 * time multiplexing of events.
 *
 * On the other hand, many monitoring tools count the common metrics
 * (cycles, instructions). It is a waste to have multiple tools create
 * multiple perf_events of "cycles" and occupy multiple PMCs.
 *
 * bperf tries to reduce such wastes by allowing multiple perf_events of
 * "cycles" or "instructions" (at different scopes) to share PMUs. Instead
 * of having each perf-stat session to read its own perf_events, bperf uses
 * BPF programs to read the perf_events and aggregate readings to BPF maps.
 * Then, the perf-stat session(s) reads the values from these BPF maps.
 *
 *                                ||
 *       shared progs and maps <- || -> per session progs and maps
 *                                ||
 *   ---------------              ||
 *   | perf_events |              ||
 *   ---------------       fexit  ||      -----------------
 *          |             --------||----> | follower prog |
 *       --------------- /        || ---  -----------------
 * cs -> | leader prog |/         ||/        |         |
 *   --> ---------------         /||  --------------  ------------------
 *  /       |         |         / ||  | filter map |  | accum_readings |
 * /  ------------  ------------  ||  --------------  ------------------
 * |  | prev map |  | diff map |  ||                        |
 * |  ------------  ------------  ||                        |
 *  \                             ||                        |
 * = \ ==================================================== | ============
 *    \                                                    /   user space
 *     \                                                  /
 *      \                                                /
 *    BPF_PROG_TEST_RUN                    BPF_MAP_LOOKUP_ELEM
 *        \                                            /
 *         \                                          /
 *          \------  perf-stat ----------------------/
 *
 * The figure above shows the architecture of bperf. Note that the figure
 * is divided into 3 regions: shared progs and maps (top left), per session
 * progs and maps (top right), and user space (bottom).
 *
 * The leader prog is triggered on each context switch (cs). The leader
 * prog reads perf_events and stores the difference (current_reading -
 * previous_reading) to the diff map. For the same metric, e.g. "cycles",
 * multiple perf-stat sessions share the same leader prog.
 *
 * Each perf-stat session creates a follower prog as fexit program to the
 * leader prog. It is possible to attach up to BPF_MAX_TRAMP_PROGS (38)
 * follower progs to the same leader prog. The follower prog checks current
 * task and processor ID to decide whether to add the value from the diff
 * map to its accumulated reading map (accum_readings).
 *
 * Finally, perf-stat user space reads the value from accum_reading map.
 *
 * Besides context switch, it is also necessary to trigger the leader prog
 * before perf-stat reads the value. Otherwise, the accum_reading map may
 * not have the latest reading from the perf_events. This is achieved by
 * triggering the event via sys_bpf(BPF_PROG_TEST_RUN) to each CPU.
 *
 * Comment before the definition of struct perf_event_attr_map_entry
 * describes how different sessions of perf-stat share information about
 * the leader prog.
 */

struct bpf_counter_ops bperf_ops = {
	.load       = bperf__load,
	.enable     = bperf__enable,
	.disable    = bperf__disable,
	.read       = bperf__read,
	.install_pe = bperf__install_pe,
	.destroy    = bperf__destroy,
};

static inline bool bpf_counter_skip(struct evsel *evsel)
{
	return list_empty(&evsel->bpf_counter_list) &&
		evsel->follower_skel == NULL;
}

int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd)
{
	if (bpf_counter_skip(evsel))
		return 0;
	return evsel->bpf_counter_ops->install_pe(evsel, cpu, fd);
}

int bpf_counter__load(struct evsel *evsel, struct target *target)
{
	if (target->bpf_str)
		evsel->bpf_counter_ops = &bpf_program_profiler_ops;
	else if (target->use_bpf || evsel->bpf_counter ||
		 evsel__match_bpf_counter_events(evsel->name))
		evsel->bpf_counter_ops = &bperf_ops;

	if (evsel->bpf_counter_ops)
		return evsel->bpf_counter_ops->load(evsel, target);
	return 0;
}

int bpf_counter__enable(struct evsel *evsel)
{
	if (bpf_counter_skip(evsel))
		return 0;
	return evsel->bpf_counter_ops->enable(evsel);
}

int bpf_counter__disable(struct evsel *evsel)
{
	if (bpf_counter_skip(evsel))
		return 0;
	return evsel->bpf_counter_ops->disable(evsel);
}

int bpf_counter__read(struct evsel *evsel)
{
	if (bpf_counter_skip(evsel))
		return -EAGAIN;
	return evsel->bpf_counter_ops->read(evsel);
}

void bpf_counter__destroy(struct evsel *evsel)
{
	if (bpf_counter_skip(evsel))
		return;
	evsel->bpf_counter_ops->destroy(evsel);
	evsel->bpf_counter_ops = NULL;
}
