// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <perf/evsel.h>
#include <perf/cpumap.h>
#include <perf/threadmap.h>
#include <linux/list.h>
#include <internal/evsel.h>
#include <linux/zalloc.h>
#include <stdlib.h>
#include <internal/xyarray.h>
#include <internal/cpumap.h>
#include <internal/mmap.h>
#include <internal/threadmap.h>
#include <internal/lib.h>
#include <linux/string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/bug.h>

void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr,
		      int idx)
{
	INIT_LIST_HEAD(&evsel->node);
	evsel->attr = *attr;
	evsel->idx  = idx;
	evsel->leader = evsel;
}

struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
{
	struct perf_evsel *evsel = zalloc(sizeof(*evsel));

	if (evsel != NULL)
		perf_evsel__init(evsel, attr, 0);

	return evsel;
}

void perf_evsel__delete(struct perf_evsel *evsel)
{
	free(evsel);
}

#define FD(_evsel, _cpu_map_idx, _thread)				\
	((int *)xyarray__entry(_evsel->fd, _cpu_map_idx, _thread))
#define MMAP(_evsel, _cpu_map_idx, _thread)				\
	(_evsel->mmap ? ((struct perf_mmap *) xyarray__entry(_evsel->mmap, _cpu_map_idx, _thread)) \
		      : NULL)

int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
{
	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));

	if (evsel->fd) {
		int idx, thread;

		for (idx = 0; idx < ncpus; idx++) {
			for (thread = 0; thread < nthreads; thread++) {
				int *fd = FD(evsel, idx, thread);

				if (fd)
					*fd = -1;
			}
		}
	}

	return evsel->fd != NULL ? 0 : -ENOMEM;
}

static int perf_evsel__alloc_mmap(struct perf_evsel *evsel, int ncpus, int nthreads)
{
	evsel->mmap = xyarray__new(ncpus, nthreads, sizeof(struct perf_mmap));

	return evsel->mmap != NULL ? 0 : -ENOMEM;
}

static int
sys_perf_event_open(struct perf_event_attr *attr,
		    pid_t pid, struct perf_cpu cpu, int group_fd,
		    unsigned long flags)
{
	return syscall(__NR_perf_event_open, attr, pid, cpu.cpu, group_fd, flags);
}

static int get_group_fd(struct perf_evsel *evsel, int cpu_map_idx, int thread, int *group_fd)
{
	struct perf_evsel *leader = evsel->leader;
	int *fd;

	if (evsel == leader) {
		*group_fd = -1;
		return 0;
	}

	/*
	 * Leader must be already processed/open,
	 * if not it's a bug.
	 */
	if (!leader->fd)
		return -ENOTCONN;

	fd = FD(leader, cpu_map_idx, thread);
	if (fd == NULL || *fd == -1)
		return -EBADF;

	*group_fd = *fd;

	return 0;
}

int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
		     struct perf_thread_map *threads)
{
	struct perf_cpu cpu;
	int idx, thread, err = 0;

	if (cpus == NULL) {
		static struct perf_cpu_map *empty_cpu_map;

		if (empty_cpu_map == NULL) {
			empty_cpu_map = perf_cpu_map__dummy_new();
			if (empty_cpu_map == NULL)
				return -ENOMEM;
		}

		cpus = empty_cpu_map;
	}

	if (threads == NULL) {
		static struct perf_thread_map *empty_thread_map;

		if (empty_thread_map == NULL) {
			empty_thread_map = perf_thread_map__new_dummy();
			if (empty_thread_map == NULL)
				return -ENOMEM;
		}

		threads = empty_thread_map;
	}

	if (evsel->fd == NULL &&
	    perf_evsel__alloc_fd(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0)
		return -ENOMEM;

	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
		for (thread = 0; thread < threads->nr; thread++) {
			int fd, group_fd, *evsel_fd;

			evsel_fd = FD(evsel, idx, thread);
			if (evsel_fd == NULL) {
				err = -EINVAL;
				goto out;
			}

			err = get_group_fd(evsel, idx, thread, &group_fd);
			if (err < 0)
				goto out;

			fd = sys_perf_event_open(&evsel->attr,
						 threads->map[thread].pid,
						 cpu, group_fd, 0);

			if (fd < 0) {
				err = -errno;
				goto out;
			}

			*evsel_fd = fd;
		}
	}
out:
	if (err)
		perf_evsel__close(evsel);

	return err;
}

static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
	int thread;

	for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
		int *fd = FD(evsel, cpu_map_idx, thread);

		if (fd && *fd >= 0) {
			close(*fd);
			*fd = -1;
		}
	}
}

void perf_evsel__close_fd(struct perf_evsel *evsel)
{
	for (int idx = 0; idx < xyarray__max_x(evsel->fd); idx++)
		perf_evsel__close_fd_cpu(evsel, idx);
}

void perf_evsel__free_fd(struct perf_evsel *evsel)
{
	xyarray__delete(evsel->fd);
	evsel->fd = NULL;
}

void perf_evsel__close(struct perf_evsel *evsel)
{
	if (evsel->fd == NULL)
		return;

	perf_evsel__close_fd(evsel);
	perf_evsel__free_fd(evsel);
}

void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
	if (evsel->fd == NULL)
		return;

	perf_evsel__close_fd_cpu(evsel, cpu_map_idx);
}

void perf_evsel__munmap(struct perf_evsel *evsel)
{
	int idx, thread;

	if (evsel->fd == NULL || evsel->mmap == NULL)
		return;

	for (idx = 0; idx < xyarray__max_x(evsel->fd); idx++) {
		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
			int *fd = FD(evsel, idx, thread);

			if (fd == NULL || *fd < 0)
				continue;

			perf_mmap__munmap(MMAP(evsel, idx, thread));
		}
	}

	xyarray__delete(evsel->mmap);
	evsel->mmap = NULL;
}

int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
{
	int ret, idx, thread;
	struct perf_mmap_param mp = {
		.prot = PROT_READ | PROT_WRITE,
		.mask = (pages * page_size) - 1,
	};

	if (evsel->fd == NULL || evsel->mmap)
		return -EINVAL;

	if (perf_evsel__alloc_mmap(evsel, xyarray__max_x(evsel->fd), xyarray__max_y(evsel->fd)) < 0)
		return -ENOMEM;

	for (idx = 0; idx < xyarray__max_x(evsel->fd); idx++) {
		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
			int *fd = FD(evsel, idx, thread);
			struct perf_mmap *map;
			struct perf_cpu cpu = perf_cpu_map__cpu(evsel->cpus, idx);

			if (fd == NULL || *fd < 0)
				continue;

			map = MMAP(evsel, idx, thread);
			perf_mmap__init(map, NULL, false, NULL);

			ret = perf_mmap__mmap(map, &mp, *fd, cpu);
			if (ret) {
				perf_evsel__munmap(evsel);
				return ret;
			}
		}
	}

	return 0;
}

void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu_map_idx, int thread)
{
	int *fd = FD(evsel, cpu_map_idx, thread);

	if (fd == NULL || *fd < 0 || MMAP(evsel, cpu_map_idx, thread) == NULL)
		return NULL;

	return MMAP(evsel, cpu_map_idx, thread)->base;
}

int perf_evsel__read_size(struct perf_evsel *evsel)
{
	u64 read_format = evsel->attr.read_format;
	int entry = sizeof(u64); /* value */
	int size = 0;
	int nr = 1;

	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
		size += sizeof(u64);

	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
		size += sizeof(u64);

	if (read_format & PERF_FORMAT_ID)
		entry += sizeof(u64);

	if (read_format & PERF_FORMAT_LOST)
		entry += sizeof(u64);

	if (read_format & PERF_FORMAT_GROUP) {
		nr = evsel->nr_members;
		size += sizeof(u64);
	}

	size += entry * nr;
	return size;
}

/* This only reads values for the leader */
static int perf_evsel__read_group(struct perf_evsel *evsel, int cpu_map_idx,
				  int thread, struct perf_counts_values *count)
{
	size_t size = perf_evsel__read_size(evsel);
	int *fd = FD(evsel, cpu_map_idx, thread);
	u64 read_format = evsel->attr.read_format;
	u64 *data;
	int idx = 1;

	if (fd == NULL || *fd < 0)
		return -EINVAL;

	data = calloc(1, size);
	if (data == NULL)
		return -ENOMEM;

	if (readn(*fd, data, size) <= 0) {
		free(data);
		return -errno;
	}

	/*
	 * This reads only the leader event intentionally since we don't have
	 * perf counts values for sibling events.
	 */
	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
		count->ena = data[idx++];
	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
		count->run = data[idx++];

	/* value is always available */
	count->val = data[idx++];
	if (read_format & PERF_FORMAT_ID)
		count->id = data[idx++];
	if (read_format & PERF_FORMAT_LOST)
		count->lost = data[idx++];

	free(data);
	return 0;
}

/*
 * The perf read format is very flexible.  It needs to set the proper
 * values according to the read format.
 */
static void perf_evsel__adjust_values(struct perf_evsel *evsel, u64 *buf,
				      struct perf_counts_values *count)
{
	u64 read_format = evsel->attr.read_format;
	int n = 0;

	count->val = buf[n++];

	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
		count->ena = buf[n++];

	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
		count->run = buf[n++];

	if (read_format & PERF_FORMAT_ID)
		count->id = buf[n++];

	if (read_format & PERF_FORMAT_LOST)
		count->lost = buf[n++];
}

int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int thread,
		     struct perf_counts_values *count)
{
	size_t size = perf_evsel__read_size(evsel);
	int *fd = FD(evsel, cpu_map_idx, thread);
	u64 read_format = evsel->attr.read_format;
	struct perf_counts_values buf;

	memset(count, 0, sizeof(*count));

	if (fd == NULL || *fd < 0)
		return -EINVAL;

	if (read_format & PERF_FORMAT_GROUP)
		return perf_evsel__read_group(evsel, cpu_map_idx, thread, count);

	if (MMAP(evsel, cpu_map_idx, thread) &&
	    !(read_format & (PERF_FORMAT_ID | PERF_FORMAT_LOST)) &&
	    !perf_mmap__read_self(MMAP(evsel, cpu_map_idx, thread), count))
		return 0;

	if (readn(*fd, buf.values, size) <= 0)
		return -errno;

	perf_evsel__adjust_values(evsel, buf.values, count);
	return 0;
}

static int perf_evsel__ioctl(struct perf_evsel *evsel, int ioc, void *arg,
			     int cpu_map_idx, int thread)
{
	int *fd = FD(evsel, cpu_map_idx, thread);

	if (fd == NULL || *fd < 0)
		return -1;

	return ioctl(*fd, ioc, arg);
}

static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
				 int ioc,  void *arg,
				 int cpu_map_idx)
{
	int thread;

	for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
		int err = perf_evsel__ioctl(evsel, ioc, arg, cpu_map_idx, thread);

		if (err)
			return err;
	}

	return 0;
}

int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
	return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, cpu_map_idx);
}

int perf_evsel__enable_thread(struct perf_evsel *evsel, int thread)
{
	struct perf_cpu cpu __maybe_unused;
	int idx;
	int err;

	perf_cpu_map__for_each_cpu(cpu, idx, evsel->cpus) {
		err = perf_evsel__ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, idx, thread);
		if (err)
			return err;
	}

	return 0;
}

int perf_evsel__enable(struct perf_evsel *evsel)
{
	int i;
	int err = 0;

	for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
		err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, i);
	return err;
}

int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
	return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, cpu_map_idx);
}

int perf_evsel__disable(struct perf_evsel *evsel)
{
	int i;
	int err = 0;

	for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
		err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, i);
	return err;
}

int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter)
{
	int err = 0, i;

	for (i = 0; i < perf_cpu_map__nr(evsel->cpus) && !err; i++)
		err = perf_evsel__run_ioctl(evsel,
				     PERF_EVENT_IOC_SET_FILTER,
				     (void *)filter, i);
	return err;
}

struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
{
	return evsel->cpus;
}

struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel)
{
	return evsel->threads;
}

struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel)
{
	return &evsel->attr;
}

int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
{
	if (ncpus == 0 || nthreads == 0)
		return 0;

	evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
	if (evsel->sample_id == NULL)
		return -ENOMEM;

	evsel->id = zalloc(ncpus * nthreads * sizeof(u64));
	if (evsel->id == NULL) {
		xyarray__delete(evsel->sample_id);
		evsel->sample_id = NULL;
		return -ENOMEM;
	}

	return 0;
}

void perf_evsel__free_id(struct perf_evsel *evsel)
{
	xyarray__delete(evsel->sample_id);
	evsel->sample_id = NULL;
	zfree(&evsel->id);
	evsel->ids = 0;
}

void perf_counts_values__scale(struct perf_counts_values *count,
			       bool scale, __s8 *pscaled)
{
	s8 scaled = 0;

	if (scale) {
		if (count->run == 0) {
			scaled = -1;
			count->val = 0;
		} else if (count->run < count->ena) {
			scaled = 1;
			count->val = (u64)((double)count->val * count->ena / count->run);
		}
	}

	if (pscaled)
		*pscaled = scaled;
}
