// SPDX-License-Identifier: GPL-2.0
/*
 * Basic resctrl file system operations
 *
 * Copyright (C) 2018 Intel Corporation
 *
 * Authors:
 *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
 *    Fenghua Yu <fenghua.yu@intel.com>
 */
#include "resctrl.h"

static int find_resctrl_mount(char *buffer)
{
	FILE *mounts;
	char line[256], *fs, *mntpoint;

	mounts = fopen("/proc/mounts", "r");
	if (!mounts) {
		perror("/proc/mounts");
		return -ENXIO;
	}
	while (!feof(mounts)) {
		if (!fgets(line, 256, mounts))
			break;
		fs = strtok(line, " \t");
		if (!fs)
			continue;
		mntpoint = strtok(NULL, " \t");
		if (!mntpoint)
			continue;
		fs = strtok(NULL, " \t");
		if (!fs)
			continue;
		if (strcmp(fs, "resctrl"))
			continue;

		fclose(mounts);
		if (buffer)
			strncpy(buffer, mntpoint, 256);

		return 0;
	}

	fclose(mounts);

	return -ENOENT;
}

/*
 * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl
 * @mum_resctrlfs:	Should the resctrl FS be remounted?
 *
 * If not mounted, mount it.
 * If mounted and mum_resctrlfs then remount resctrl FS.
 * If mounted and !mum_resctrlfs then noop
 *
 * Return: 0 on success, non-zero on failure
 */
int remount_resctrlfs(bool mum_resctrlfs)
{
	char mountpoint[256];
	int ret;

	ret = find_resctrl_mount(mountpoint);
	if (ret)
		strcpy(mountpoint, RESCTRL_PATH);

	if (!ret && mum_resctrlfs && umount(mountpoint))
		ksft_print_msg("Fail: unmounting \"%s\"\n", mountpoint);

	if (!ret && !mum_resctrlfs)
		return 0;

	ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH);
	ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL);
	if (ret)
		perror("# mount");

	return ret;
}

int umount_resctrlfs(void)
{
	if (find_resctrl_mount(NULL))
		return 0;

	if (umount(RESCTRL_PATH)) {
		perror("# Unable to umount resctrl");

		return errno;
	}

	return 0;
}

/*
 * get_resource_id - Get socket number/l3 id for a specified CPU
 * @cpu_no:	CPU number
 * @resource_id: Socket number or l3_id
 *
 * Return: >= 0 on success, < 0 on failure.
 */
int get_resource_id(int cpu_no, int *resource_id)
{
	char phys_pkg_path[1024];
	FILE *fp;

	if (is_amd)
		sprintf(phys_pkg_path, "%s%d/cache/index3/id",
			PHYS_ID_PATH, cpu_no);
	else
		sprintf(phys_pkg_path, "%s%d/topology/physical_package_id",
			PHYS_ID_PATH, cpu_no);

	fp = fopen(phys_pkg_path, "r");
	if (!fp) {
		perror("Failed to open physical_package_id");

		return -1;
	}
	if (fscanf(fp, "%d", resource_id) <= 0) {
		perror("Could not get socket number or l3 id");
		fclose(fp);

		return -1;
	}
	fclose(fp);

	return 0;
}

/*
 * get_cache_size - Get cache size for a specified CPU
 * @cpu_no:	CPU number
 * @cache_type:	Cache level L2/L3
 * @cache_size:	pointer to cache_size
 *
 * Return: = 0 on success, < 0 on failure.
 */
int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size)
{
	char cache_path[1024], cache_str[64];
	int length, i, cache_num;
	FILE *fp;

	if (!strcmp(cache_type, "L3")) {
		cache_num = 3;
	} else if (!strcmp(cache_type, "L2")) {
		cache_num = 2;
	} else {
		perror("Invalid cache level");
		return -1;
	}

	sprintf(cache_path, "/sys/bus/cpu/devices/cpu%d/cache/index%d/size",
		cpu_no, cache_num);
	fp = fopen(cache_path, "r");
	if (!fp) {
		perror("Failed to open cache size");

		return -1;
	}
	if (fscanf(fp, "%s", cache_str) <= 0) {
		perror("Could not get cache_size");
		fclose(fp);

		return -1;
	}
	fclose(fp);

	length = (int)strlen(cache_str);

	*cache_size = 0;

	for (i = 0; i < length; i++) {
		if ((cache_str[i] >= '0') && (cache_str[i] <= '9'))

			*cache_size = *cache_size * 10 + (cache_str[i] - '0');

		else if (cache_str[i] == 'K')

			*cache_size = *cache_size * 1024;

		else if (cache_str[i] == 'M')

			*cache_size = *cache_size * 1024 * 1024;

		else
			break;
	}

	return 0;
}

#define CORE_SIBLINGS_PATH	"/sys/bus/cpu/devices/cpu"

/*
 * get_cbm_mask - Get cbm mask for given cache
 * @cache_type:	Cache level L2/L3
 * @cbm_mask:	cbm_mask returned as a string
 *
 * Return: = 0 on success, < 0 on failure.
 */
int get_cbm_mask(char *cache_type, char *cbm_mask)
{
	char cbm_mask_path[1024];
	FILE *fp;

	if (!cbm_mask)
		return -1;

	sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type);

	fp = fopen(cbm_mask_path, "r");
	if (!fp) {
		perror("Failed to open cache level");

		return -1;
	}
	if (fscanf(fp, "%s", cbm_mask) <= 0) {
		perror("Could not get max cbm_mask");
		fclose(fp);

		return -1;
	}
	fclose(fp);

	return 0;
}

/*
 * get_core_sibling - Get sibling core id from the same socket for given CPU
 * @cpu_no:	CPU number
 *
 * Return:	> 0 on success, < 0 on failure.
 */
int get_core_sibling(int cpu_no)
{
	char core_siblings_path[1024], cpu_list_str[64];
	int sibling_cpu_no = -1;
	FILE *fp;

	sprintf(core_siblings_path, "%s%d/topology/core_siblings_list",
		CORE_SIBLINGS_PATH, cpu_no);

	fp = fopen(core_siblings_path, "r");
	if (!fp) {
		perror("Failed to open core siblings path");

		return -1;
	}
	if (fscanf(fp, "%s", cpu_list_str) <= 0) {
		perror("Could not get core_siblings list");
		fclose(fp);

		return -1;
	}
	fclose(fp);

	char *token = strtok(cpu_list_str, "-,");

	while (token) {
		sibling_cpu_no = atoi(token);
		/* Skipping core 0 as we don't want to run test on core 0 */
		if (sibling_cpu_no != 0 && sibling_cpu_no != cpu_no)
			break;
		token = strtok(NULL, "-,");
	}

	return sibling_cpu_no;
}

/*
 * taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu
 * @bm_pid:	PID that should be binded
 * @cpu_no:	CPU number at which the PID would be binded
 *
 * Return: 0 on success, non-zero on failure
 */
int taskset_benchmark(pid_t bm_pid, int cpu_no)
{
	cpu_set_t my_set;

	CPU_ZERO(&my_set);
	CPU_SET(cpu_no, &my_set);

	if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) {
		perror("Unable to taskset benchmark");

		return -1;
	}

	return 0;
}

/*
 * run_benchmark - Run a specified benchmark or fill_buf (default benchmark)
 *		   in specified signal. Direct benchmark stdio to /dev/null.
 * @signum:	signal number
 * @info:	signal info
 * @ucontext:	user context in signal handling
 *
 * Return: void
 */
void run_benchmark(int signum, siginfo_t *info, void *ucontext)
{
	int operation, ret, malloc_and_init_memory, memflush;
	unsigned long span, buffer_span;
	char **benchmark_cmd;
	char resctrl_val[64];
	FILE *fp;

	benchmark_cmd = info->si_ptr;

	/*
	 * Direct stdio of child to /dev/null, so that only parent writes to
	 * stdio (console)
	 */
	fp = freopen("/dev/null", "w", stdout);
	if (!fp)
		PARENT_EXIT("Unable to direct benchmark status to /dev/null");

	if (strcmp(benchmark_cmd[0], "fill_buf") == 0) {
		/* Execute default fill_buf benchmark */
		span = strtoul(benchmark_cmd[1], NULL, 10);
		malloc_and_init_memory = atoi(benchmark_cmd[2]);
		memflush =  atoi(benchmark_cmd[3]);
		operation = atoi(benchmark_cmd[4]);
		sprintf(resctrl_val, "%s", benchmark_cmd[5]);

		if (strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
			buffer_span = span * MB;
		else
			buffer_span = span;

		if (run_fill_buf(buffer_span, malloc_and_init_memory, memflush,
				 operation, resctrl_val))
			fprintf(stderr, "Error in running fill buffer\n");
	} else {
		/* Execute specified benchmark */
		ret = execvp(benchmark_cmd[0], benchmark_cmd);
		if (ret)
			perror("wrong\n");
	}

	fclose(stdout);
	PARENT_EXIT("Unable to run specified benchmark");
}

/*
 * create_grp - Create a group only if one doesn't exist
 * @grp_name:	Name of the group
 * @grp:	Full path and name of the group
 * @parent_grp:	Full path and name of the parent group
 *
 * Return: 0 on success, non-zero on failure
 */
static int create_grp(const char *grp_name, char *grp, const char *parent_grp)
{
	int found_grp = 0;
	struct dirent *ep;
	DIR *dp;

	/*
	 * At this point, we are guaranteed to have resctrl FS mounted and if
	 * length of grp_name == 0, it means, user wants to use root con_mon
	 * grp, so do nothing
	 */
	if (strlen(grp_name) == 0)
		return 0;

	/* Check if requested grp exists or not */
	dp = opendir(parent_grp);
	if (dp) {
		while ((ep = readdir(dp)) != NULL) {
			if (strcmp(ep->d_name, grp_name) == 0)
				found_grp = 1;
		}
		closedir(dp);
	} else {
		perror("Unable to open resctrl for group");

		return -1;
	}

	/* Requested grp doesn't exist, hence create it */
	if (found_grp == 0) {
		if (mkdir(grp, 0) == -1) {
			perror("Unable to create group");

			return -1;
		}
	}

	return 0;
}

static int write_pid_to_tasks(char *tasks, pid_t pid)
{
	FILE *fp;

	fp = fopen(tasks, "w");
	if (!fp) {
		perror("Failed to open tasks file");

		return -1;
	}
	if (fprintf(fp, "%d\n", pid) < 0) {
		perror("Failed to wr pid to tasks file");
		fclose(fp);

		return -1;
	}
	fclose(fp);

	return 0;
}

/*
 * write_bm_pid_to_resctrl - Write a PID (i.e. benchmark) to resctrl FS
 * @bm_pid:		PID that should be written
 * @ctrlgrp:		Name of the control monitor group (con_mon grp)
 * @mongrp:		Name of the monitor group (mon grp)
 * @resctrl_val:	Resctrl feature (Eg: mbm, mba.. etc)
 *
 * If a con_mon grp is requested, create it and write pid to it, otherwise
 * write pid to root con_mon grp.
 * If a mon grp is requested, create it and write pid to it, otherwise
 * pid is not written, this means that pid is in con_mon grp and hence
 * should consult con_mon grp's mon_data directory for results.
 *
 * Return: 0 on success, non-zero on failure
 */
int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
			    char *resctrl_val)
{
	char controlgroup[128], monitorgroup[512], monitorgroup_p[256];
	char tasks[1024];
	int ret = 0;

	if (strlen(ctrlgrp))
		sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp);
	else
		sprintf(controlgroup, "%s", RESCTRL_PATH);

	/* Create control and monitoring group and write pid into it */
	ret = create_grp(ctrlgrp, controlgroup, RESCTRL_PATH);
	if (ret)
		goto out;
	sprintf(tasks, "%s/tasks", controlgroup);
	ret = write_pid_to_tasks(tasks, bm_pid);
	if (ret)
		goto out;

	/* Create mon grp and write pid into it for "mbm" and "cmt" test */
	if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)) ||
	    !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
		if (strlen(mongrp)) {
			sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
			sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
			ret = create_grp(mongrp, monitorgroup, monitorgroup_p);
			if (ret)
				goto out;

			sprintf(tasks, "%s/mon_groups/%s/tasks",
				controlgroup, mongrp);
			ret = write_pid_to_tasks(tasks, bm_pid);
			if (ret)
				goto out;
		}
	}

out:
	ksft_print_msg("Writing benchmark parameters to resctrl FS\n");
	if (ret)
		perror("# writing to resctrlfs");

	return ret;
}

/*
 * write_schemata - Update schemata of a con_mon grp
 * @ctrlgrp:		Name of the con_mon grp
 * @schemata:		Schemata that should be updated to
 * @cpu_no:		CPU number that the benchmark PID is binded to
 * @resctrl_val:	Resctrl feature (Eg: mbm, mba.. etc)
 *
 * Update schemata of a con_mon grp *only* if requested resctrl feature is
 * allocation type
 *
 * Return: 0 on success, non-zero on failure
 */
int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
{
	char controlgroup[1024], schema[1024], reason[64];
	int resource_id, ret = 0;
	FILE *fp;

	if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
	    strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
	    strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
		return -ENOENT;

	if (!schemata) {
		ksft_print_msg("Skipping empty schemata update\n");

		return -1;
	}

	if (get_resource_id(cpu_no, &resource_id) < 0) {
		sprintf(reason, "Failed to get resource id");
		ret = -1;

		goto out;
	}

	if (strlen(ctrlgrp) != 0)
		sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp);
	else
		sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);

	if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
	    !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
		sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
	if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)))
		sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);

	fp = fopen(controlgroup, "w");
	if (!fp) {
		sprintf(reason, "Failed to open control group");
		ret = -1;

		goto out;
	}

	if (fprintf(fp, "%s\n", schema) < 0) {
		sprintf(reason, "Failed to write schemata in control group");
		fclose(fp);
		ret = -1;

		goto out;
	}
	fclose(fp);

out:
	ksft_print_msg("Write schema \"%s\" to resctrl FS%s%s\n",
		       schema, ret ? " # " : "",
		       ret ? reason : "");

	return ret;
}

bool check_resctrlfs_support(void)
{
	FILE *inf = fopen("/proc/filesystems", "r");
	DIR *dp;
	char *res;
	bool ret = false;

	if (!inf)
		return false;

	res = fgrep(inf, "nodev\tresctrl\n");

	if (res) {
		ret = true;
		free(res);
	}

	fclose(inf);

	ksft_print_msg("%s Check kernel supports resctrl filesystem\n",
		       ret ? "Pass:" : "Fail:");

	if (!ret)
		return ret;

	dp = opendir(RESCTRL_PATH);
	ksft_print_msg("%s Check resctrl mountpoint \"%s\" exists\n",
		       dp ? "Pass:" : "Fail:", RESCTRL_PATH);
	if (dp)
		closedir(dp);

	ksft_print_msg("resctrl filesystem %s mounted\n",
		       find_resctrl_mount(NULL) ? "not" : "is");

	return ret;
}

char *fgrep(FILE *inf, const char *str)
{
	char line[256];
	int slen = strlen(str);

	while (!feof(inf)) {
		if (!fgets(line, 256, inf))
			break;
		if (strncmp(line, str, slen))
			continue;

		return strdup(line);
	}

	return NULL;
}

/*
 * validate_resctrl_feature_request - Check if requested feature is valid.
 * @resctrl_val:	Requested feature
 *
 * Return: True if the feature is supported, else false
 */
bool validate_resctrl_feature_request(const char *resctrl_val)
{
	struct stat statbuf;
	bool found = false;
	char *res;
	FILE *inf;

	if (!resctrl_val)
		return false;

	if (remount_resctrlfs(false))
		return false;

	if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
		if (!stat(L3_PATH, &statbuf))
			return true;
	} else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
		if (!stat(MB_PATH, &statbuf))
			return true;
	} else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
		   !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
		if (!stat(L3_MON_PATH, &statbuf)) {
			inf = fopen(L3_MON_FEATURES_PATH, "r");
			if (!inf)
				return false;

			if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
				res = fgrep(inf, "llc_occupancy");
				if (res) {
					found = true;
					free(res);
				}
			}

			if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
				res = fgrep(inf, "mbm_total_bytes");
				if (res) {
					free(res);
					res = fgrep(inf, "mbm_local_bytes");
					if (res) {
						found = true;
						free(res);
					}
				}
			}
			fclose(inf);
		}
	}

	return found;
}

int filter_dmesg(void)
{
	char line[1024];
	FILE *fp;
	int pipefds[2];
	pid_t pid;
	int ret;

	ret = pipe(pipefds);
	if (ret) {
		perror("pipe");
		return ret;
	}
	pid = fork();
	if (pid == 0) {
		close(pipefds[0]);
		dup2(pipefds[1], STDOUT_FILENO);
		execlp("dmesg", "dmesg", NULL);
		perror("executing dmesg");
		exit(1);
	}
	close(pipefds[1]);
	fp = fdopen(pipefds[0], "r");
	if (!fp) {
		perror("fdopen(pipe)");
		kill(pid, SIGTERM);

		return -1;
	}

	while (fgets(line, 1024, fp)) {
		if (strstr(line, "intel_rdt:"))
			ksft_print_msg("dmesg: %s", line);
		if (strstr(line, "resctrl:"))
			ksft_print_msg("dmesg: %s", line);
	}
	fclose(fp);
	waitpid(pid, NULL, 0);

	return 0;
}

int validate_bw_report_request(char *bw_report)
{
	if (strcmp(bw_report, "reads") == 0)
		return 0;
	if (strcmp(bw_report, "writes") == 0)
		return 0;
	if (strcmp(bw_report, "nt-writes") == 0) {
		strcpy(bw_report, "writes");
		return 0;
	}
	if (strcmp(bw_report, "total") == 0)
		return 0;

	fprintf(stderr, "Requested iMC B/W report type unavailable\n");

	return -1;
}

int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
		    int group_fd, unsigned long flags)
{
	int ret;

	ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
		      group_fd, flags);
	return ret;
}

unsigned int count_bits(unsigned long n)
{
	unsigned int count = 0;

	while (n) {
		count += n & 1;
		n >>= 1;
	}

	return count;
}
