xref: /linux/tools/testing/selftests/resctrl/resctrlfs.c (revision 4b357e2a6d6c364a88d50526675fe596a30766cb)
1591a6e85SSai Praneeth Prakhya // SPDX-License-Identifier: GPL-2.0
2591a6e85SSai Praneeth Prakhya /*
3591a6e85SSai Praneeth Prakhya  * Basic resctrl file system operations
4591a6e85SSai Praneeth Prakhya  *
5591a6e85SSai Praneeth Prakhya  * Copyright (C) 2018 Intel Corporation
6591a6e85SSai Praneeth Prakhya  *
7591a6e85SSai Praneeth Prakhya  * Authors:
8591a6e85SSai Praneeth Prakhya  *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
9591a6e85SSai Praneeth Prakhya  *    Fenghua Yu <fenghua.yu@intel.com>
10591a6e85SSai Praneeth Prakhya  */
1120d96b25SMaciej Wieczor-Retman #include <fcntl.h>
12d56e5da0SIlpo Järvinen #include <limits.h>
13d56e5da0SIlpo Järvinen 
14591a6e85SSai Praneeth Prakhya #include "resctrl.h"
15591a6e85SSai Praneeth Prakhya 
16591a6e85SSai Praneeth Prakhya static int find_resctrl_mount(char *buffer)
17591a6e85SSai Praneeth Prakhya {
18591a6e85SSai Praneeth Prakhya 	FILE *mounts;
19591a6e85SSai Praneeth Prakhya 	char line[256], *fs, *mntpoint;
20591a6e85SSai Praneeth Prakhya 
21591a6e85SSai Praneeth Prakhya 	mounts = fopen("/proc/mounts", "r");
22591a6e85SSai Praneeth Prakhya 	if (!mounts) {
23cc8ff7f5SIlpo Järvinen 		ksft_perror("/proc/mounts");
24591a6e85SSai Praneeth Prakhya 		return -ENXIO;
25591a6e85SSai Praneeth Prakhya 	}
26591a6e85SSai Praneeth Prakhya 	while (!feof(mounts)) {
27591a6e85SSai Praneeth Prakhya 		if (!fgets(line, 256, mounts))
28591a6e85SSai Praneeth Prakhya 			break;
29591a6e85SSai Praneeth Prakhya 		fs = strtok(line, " \t");
30591a6e85SSai Praneeth Prakhya 		if (!fs)
31591a6e85SSai Praneeth Prakhya 			continue;
32591a6e85SSai Praneeth Prakhya 		mntpoint = strtok(NULL, " \t");
33591a6e85SSai Praneeth Prakhya 		if (!mntpoint)
34591a6e85SSai Praneeth Prakhya 			continue;
35591a6e85SSai Praneeth Prakhya 		fs = strtok(NULL, " \t");
36591a6e85SSai Praneeth Prakhya 		if (!fs)
37591a6e85SSai Praneeth Prakhya 			continue;
38591a6e85SSai Praneeth Prakhya 		if (strcmp(fs, "resctrl"))
39591a6e85SSai Praneeth Prakhya 			continue;
40591a6e85SSai Praneeth Prakhya 
41591a6e85SSai Praneeth Prakhya 		fclose(mounts);
42591a6e85SSai Praneeth Prakhya 		if (buffer)
43591a6e85SSai Praneeth Prakhya 			strncpy(buffer, mntpoint, 256);
44591a6e85SSai Praneeth Prakhya 
45591a6e85SSai Praneeth Prakhya 		return 0;
46591a6e85SSai Praneeth Prakhya 	}
47591a6e85SSai Praneeth Prakhya 
48591a6e85SSai Praneeth Prakhya 	fclose(mounts);
49591a6e85SSai Praneeth Prakhya 
50591a6e85SSai Praneeth Prakhya 	return -ENOENT;
51591a6e85SSai Praneeth Prakhya }
52591a6e85SSai Praneeth Prakhya 
53591a6e85SSai Praneeth Prakhya /*
546383851aSIlpo Järvinen  * mount_resctrlfs - Mount resctrl FS at /sys/fs/resctrl
55591a6e85SSai Praneeth Prakhya  *
566383851aSIlpo Järvinen  * Mounts resctrl FS. Fails if resctrl FS is already mounted to avoid
576383851aSIlpo Järvinen  * pre-existing settings interfering with the test results.
58591a6e85SSai Praneeth Prakhya  *
5934813938SIlpo Järvinen  * Return: 0 on success, < 0 on error.
60591a6e85SSai Praneeth Prakhya  */
616383851aSIlpo Järvinen int mount_resctrlfs(void)
62591a6e85SSai Praneeth Prakhya {
63591a6e85SSai Praneeth Prakhya 	int ret;
64591a6e85SSai Praneeth Prakhya 
656383851aSIlpo Järvinen 	ret = find_resctrl_mount(NULL);
666383851aSIlpo Järvinen 	if (ret != -ENOENT)
676383851aSIlpo Järvinen 		return -1;
68591a6e85SSai Praneeth Prakhya 
69ca2f4214SFenghua Yu 	ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH);
70591a6e85SSai Praneeth Prakhya 	ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL);
71591a6e85SSai Praneeth Prakhya 	if (ret)
72cc8ff7f5SIlpo Järvinen 		ksft_perror("mount");
73591a6e85SSai Praneeth Prakhya 
74591a6e85SSai Praneeth Prakhya 	return ret;
75591a6e85SSai Praneeth Prakhya }
76591a6e85SSai Praneeth Prakhya 
77591a6e85SSai Praneeth Prakhya int umount_resctrlfs(void)
78591a6e85SSai Praneeth Prakhya {
79ede13008SIlpo Järvinen 	char mountpoint[256];
80ede13008SIlpo Järvinen 	int ret;
814e5cb354SFenghua Yu 
82ede13008SIlpo Järvinen 	ret = find_resctrl_mount(mountpoint);
83ede13008SIlpo Järvinen 	if (ret == -ENOENT)
84ede13008SIlpo Järvinen 		return 0;
85ede13008SIlpo Järvinen 	if (ret)
86ede13008SIlpo Järvinen 		return ret;
87ede13008SIlpo Järvinen 
88ede13008SIlpo Järvinen 	if (umount(mountpoint)) {
89cc8ff7f5SIlpo Järvinen 		ksft_perror("Unable to umount resctrl");
90591a6e85SSai Praneeth Prakhya 
91c90fba60SIlpo Järvinen 		return -1;
92591a6e85SSai Praneeth Prakhya 	}
93591a6e85SSai Praneeth Prakhya 
94591a6e85SSai Praneeth Prakhya 	return 0;
95591a6e85SSai Praneeth Prakhya }
96591a6e85SSai Praneeth Prakhya 
97591a6e85SSai Praneeth Prakhya /*
98591a6e85SSai Praneeth Prakhya  * get_resource_id - Get socket number/l3 id for a specified CPU
99591a6e85SSai Praneeth Prakhya  * @cpu_no:	CPU number
100591a6e85SSai Praneeth Prakhya  * @resource_id: Socket number or l3_id
101591a6e85SSai Praneeth Prakhya  *
102591a6e85SSai Praneeth Prakhya  * Return: >= 0 on success, < 0 on failure.
103591a6e85SSai Praneeth Prakhya  */
104591a6e85SSai Praneeth Prakhya int get_resource_id(int cpu_no, int *resource_id)
105591a6e85SSai Praneeth Prakhya {
106591a6e85SSai Praneeth Prakhya 	char phys_pkg_path[1024];
107591a6e85SSai Praneeth Prakhya 	FILE *fp;
108591a6e85SSai Praneeth Prakhya 
1096220f69eSShaopeng Tan 	if (get_vendor() == ARCH_AMD)
110c0327e1dSBabu Moger 		sprintf(phys_pkg_path, "%s%d/cache/index3/id",
111c0327e1dSBabu Moger 			PHYS_ID_PATH, cpu_no);
112c0327e1dSBabu Moger 	else
113591a6e85SSai Praneeth Prakhya 		sprintf(phys_pkg_path, "%s%d/topology/physical_package_id",
114591a6e85SSai Praneeth Prakhya 			PHYS_ID_PATH, cpu_no);
115c0327e1dSBabu Moger 
116591a6e85SSai Praneeth Prakhya 	fp = fopen(phys_pkg_path, "r");
117591a6e85SSai Praneeth Prakhya 	if (!fp) {
118cc8ff7f5SIlpo Järvinen 		ksft_perror("Failed to open physical_package_id");
119591a6e85SSai Praneeth Prakhya 
120591a6e85SSai Praneeth Prakhya 		return -1;
121591a6e85SSai Praneeth Prakhya 	}
122591a6e85SSai Praneeth Prakhya 	if (fscanf(fp, "%d", resource_id) <= 0) {
123cc8ff7f5SIlpo Järvinen 		ksft_perror("Could not get socket number or l3 id");
124591a6e85SSai Praneeth Prakhya 		fclose(fp);
125591a6e85SSai Praneeth Prakhya 
126591a6e85SSai Praneeth Prakhya 		return -1;
127591a6e85SSai Praneeth Prakhya 	}
128591a6e85SSai Praneeth Prakhya 	fclose(fp);
129591a6e85SSai Praneeth Prakhya 
130591a6e85SSai Praneeth Prakhya 	return 0;
131591a6e85SSai Praneeth Prakhya }
132591a6e85SSai Praneeth Prakhya 
133591a6e85SSai Praneeth Prakhya /*
13478941183SFenghua Yu  * get_cache_size - Get cache size for a specified CPU
13578941183SFenghua Yu  * @cpu_no:	CPU number
13678941183SFenghua Yu  * @cache_type:	Cache level L2/L3
13778941183SFenghua Yu  * @cache_size:	pointer to cache_size
13878941183SFenghua Yu  *
13978941183SFenghua Yu  * Return: = 0 on success, < 0 on failure.
14078941183SFenghua Yu  */
14178941183SFenghua Yu int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size)
14278941183SFenghua Yu {
14378941183SFenghua Yu 	char cache_path[1024], cache_str[64];
14478941183SFenghua Yu 	int length, i, cache_num;
14578941183SFenghua Yu 	FILE *fp;
14678941183SFenghua Yu 
14778941183SFenghua Yu 	if (!strcmp(cache_type, "L3")) {
14878941183SFenghua Yu 		cache_num = 3;
14978941183SFenghua Yu 	} else if (!strcmp(cache_type, "L2")) {
15078941183SFenghua Yu 		cache_num = 2;
15178941183SFenghua Yu 	} else {
152cc8ff7f5SIlpo Järvinen 		ksft_print_msg("Invalid cache level\n");
15378941183SFenghua Yu 		return -1;
15478941183SFenghua Yu 	}
15578941183SFenghua Yu 
15678941183SFenghua Yu 	sprintf(cache_path, "/sys/bus/cpu/devices/cpu%d/cache/index%d/size",
15778941183SFenghua Yu 		cpu_no, cache_num);
15878941183SFenghua Yu 	fp = fopen(cache_path, "r");
15978941183SFenghua Yu 	if (!fp) {
160cc8ff7f5SIlpo Järvinen 		ksft_perror("Failed to open cache size");
16178941183SFenghua Yu 
16278941183SFenghua Yu 		return -1;
16378941183SFenghua Yu 	}
16478941183SFenghua Yu 	if (fscanf(fp, "%s", cache_str) <= 0) {
165cc8ff7f5SIlpo Järvinen 		ksft_perror("Could not get cache_size");
16678941183SFenghua Yu 		fclose(fp);
16778941183SFenghua Yu 
16878941183SFenghua Yu 		return -1;
16978941183SFenghua Yu 	}
17078941183SFenghua Yu 	fclose(fp);
17178941183SFenghua Yu 
17278941183SFenghua Yu 	length = (int)strlen(cache_str);
17378941183SFenghua Yu 
17478941183SFenghua Yu 	*cache_size = 0;
17578941183SFenghua Yu 
17678941183SFenghua Yu 	for (i = 0; i < length; i++) {
17778941183SFenghua Yu 		if ((cache_str[i] >= '0') && (cache_str[i] <= '9'))
17878941183SFenghua Yu 
17978941183SFenghua Yu 			*cache_size = *cache_size * 10 + (cache_str[i] - '0');
18078941183SFenghua Yu 
18178941183SFenghua Yu 		else if (cache_str[i] == 'K')
18278941183SFenghua Yu 
18378941183SFenghua Yu 			*cache_size = *cache_size * 1024;
18478941183SFenghua Yu 
18578941183SFenghua Yu 		else if (cache_str[i] == 'M')
18678941183SFenghua Yu 
18778941183SFenghua Yu 			*cache_size = *cache_size * 1024 * 1024;
18878941183SFenghua Yu 
18978941183SFenghua Yu 		else
19078941183SFenghua Yu 			break;
19178941183SFenghua Yu 	}
19278941183SFenghua Yu 
19378941183SFenghua Yu 	return 0;
19478941183SFenghua Yu }
19578941183SFenghua Yu 
19678941183SFenghua Yu #define CORE_SIBLINGS_PATH	"/sys/bus/cpu/devices/cpu"
19778941183SFenghua Yu 
19878941183SFenghua Yu /*
199*4b357e2aSIlpo Järvinen  * get_bit_mask - Get bit mask from given file
200*4b357e2aSIlpo Järvinen  * @filename:	File containing the mask
201*4b357e2aSIlpo Järvinen  * @mask:	The bit mask returned as unsigned long
20278941183SFenghua Yu  *
20378941183SFenghua Yu  * Return: = 0 on success, < 0 on failure.
20478941183SFenghua Yu  */
205*4b357e2aSIlpo Järvinen static int get_bit_mask(const char *filename, unsigned long *mask)
20678941183SFenghua Yu {
20778941183SFenghua Yu 	FILE *fp;
20878941183SFenghua Yu 
209*4b357e2aSIlpo Järvinen 	if (!filename || !mask)
2108236c51dSFenghua Yu 		return -1;
2118236c51dSFenghua Yu 
212*4b357e2aSIlpo Järvinen 	fp = fopen(filename, "r");
21378941183SFenghua Yu 	if (!fp) {
214*4b357e2aSIlpo Järvinen 		ksft_print_msg("Failed to open bit mask file '%s': %s\n",
215*4b357e2aSIlpo Järvinen 			       filename, strerror(errno));
21678941183SFenghua Yu 		return -1;
21778941183SFenghua Yu 	}
218*4b357e2aSIlpo Järvinen 
219*4b357e2aSIlpo Järvinen 	if (fscanf(fp, "%lx", mask) <= 0) {
220*4b357e2aSIlpo Järvinen 		ksft_print_msg("Could not read bit mask file '%s': %s\n",
221*4b357e2aSIlpo Järvinen 			       filename, strerror(errno));
22278941183SFenghua Yu 		fclose(fp);
22378941183SFenghua Yu 
22478941183SFenghua Yu 		return -1;
22578941183SFenghua Yu 	}
22678941183SFenghua Yu 	fclose(fp);
22778941183SFenghua Yu 
22878941183SFenghua Yu 	return 0;
22978941183SFenghua Yu }
23078941183SFenghua Yu 
23178941183SFenghua Yu /*
232*4b357e2aSIlpo Järvinen  * get_full_cbm - Get full Cache Bit Mask (CBM)
233*4b357e2aSIlpo Järvinen  * @cache_type:	Cache type as "L2" or "L3"
234*4b357e2aSIlpo Järvinen  * @mask:	Full cache bit mask representing the maximal portion of cache
235*4b357e2aSIlpo Järvinen  *		available for allocation, returned as unsigned long.
236*4b357e2aSIlpo Järvinen  *
237*4b357e2aSIlpo Järvinen  * Return: = 0 on success, < 0 on failure.
238*4b357e2aSIlpo Järvinen  */
239*4b357e2aSIlpo Järvinen int get_full_cbm(const char *cache_type, unsigned long *mask)
240*4b357e2aSIlpo Järvinen {
241*4b357e2aSIlpo Järvinen 	char cbm_path[PATH_MAX];
242*4b357e2aSIlpo Järvinen 	int ret;
243*4b357e2aSIlpo Järvinen 
244*4b357e2aSIlpo Järvinen 	if (!cache_type)
245*4b357e2aSIlpo Järvinen 		return -1;
246*4b357e2aSIlpo Järvinen 
247*4b357e2aSIlpo Järvinen 	snprintf(cbm_path, sizeof(cbm_path), "%s/%s/cbm_mask",
248*4b357e2aSIlpo Järvinen 		 INFO_PATH, cache_type);
249*4b357e2aSIlpo Järvinen 
250*4b357e2aSIlpo Järvinen 	ret = get_bit_mask(cbm_path, mask);
251*4b357e2aSIlpo Järvinen 	if (ret || !*mask)
252*4b357e2aSIlpo Järvinen 		return -1;
253*4b357e2aSIlpo Järvinen 
254*4b357e2aSIlpo Järvinen 	return 0;
255*4b357e2aSIlpo Järvinen }
256*4b357e2aSIlpo Järvinen 
257*4b357e2aSIlpo Järvinen /*
25878941183SFenghua Yu  * get_core_sibling - Get sibling core id from the same socket for given CPU
25978941183SFenghua Yu  * @cpu_no:	CPU number
26078941183SFenghua Yu  *
26178941183SFenghua Yu  * Return:	> 0 on success, < 0 on failure.
26278941183SFenghua Yu  */
26378941183SFenghua Yu int get_core_sibling(int cpu_no)
26478941183SFenghua Yu {
26578941183SFenghua Yu 	char core_siblings_path[1024], cpu_list_str[64];
26678941183SFenghua Yu 	int sibling_cpu_no = -1;
26778941183SFenghua Yu 	FILE *fp;
26878941183SFenghua Yu 
26978941183SFenghua Yu 	sprintf(core_siblings_path, "%s%d/topology/core_siblings_list",
27078941183SFenghua Yu 		CORE_SIBLINGS_PATH, cpu_no);
27178941183SFenghua Yu 
27278941183SFenghua Yu 	fp = fopen(core_siblings_path, "r");
27378941183SFenghua Yu 	if (!fp) {
274cc8ff7f5SIlpo Järvinen 		ksft_perror("Failed to open core siblings path");
27578941183SFenghua Yu 
27678941183SFenghua Yu 		return -1;
27778941183SFenghua Yu 	}
27878941183SFenghua Yu 	if (fscanf(fp, "%s", cpu_list_str) <= 0) {
279cc8ff7f5SIlpo Järvinen 		ksft_perror("Could not get core_siblings list");
28078941183SFenghua Yu 		fclose(fp);
28178941183SFenghua Yu 
28278941183SFenghua Yu 		return -1;
28378941183SFenghua Yu 	}
28478941183SFenghua Yu 	fclose(fp);
28578941183SFenghua Yu 
28678941183SFenghua Yu 	char *token = strtok(cpu_list_str, "-,");
28778941183SFenghua Yu 
28878941183SFenghua Yu 	while (token) {
28978941183SFenghua Yu 		sibling_cpu_no = atoi(token);
29078941183SFenghua Yu 		/* Skipping core 0 as we don't want to run test on core 0 */
291f5f16ae4SReinette Chatre 		if (sibling_cpu_no != 0 && sibling_cpu_no != cpu_no)
29278941183SFenghua Yu 			break;
29378941183SFenghua Yu 		token = strtok(NULL, "-,");
29478941183SFenghua Yu 	}
29578941183SFenghua Yu 
29678941183SFenghua Yu 	return sibling_cpu_no;
29778941183SFenghua Yu }
29878941183SFenghua Yu 
29978941183SFenghua Yu /*
300591a6e85SSai Praneeth Prakhya  * taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu
301591a6e85SSai Praneeth Prakhya  * @bm_pid:	PID that should be binded
302591a6e85SSai Praneeth Prakhya  * @cpu_no:	CPU number at which the PID would be binded
303591a6e85SSai Praneeth Prakhya  *
30434813938SIlpo Järvinen  * Return: 0 on success, < 0 on error.
305591a6e85SSai Praneeth Prakhya  */
306591a6e85SSai Praneeth Prakhya int taskset_benchmark(pid_t bm_pid, int cpu_no)
307591a6e85SSai Praneeth Prakhya {
308591a6e85SSai Praneeth Prakhya 	cpu_set_t my_set;
309591a6e85SSai Praneeth Prakhya 
310591a6e85SSai Praneeth Prakhya 	CPU_ZERO(&my_set);
311591a6e85SSai Praneeth Prakhya 	CPU_SET(cpu_no, &my_set);
312591a6e85SSai Praneeth Prakhya 
313591a6e85SSai Praneeth Prakhya 	if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) {
314cc8ff7f5SIlpo Järvinen 		ksft_perror("Unable to taskset benchmark");
315591a6e85SSai Praneeth Prakhya 
316591a6e85SSai Praneeth Prakhya 		return -1;
317591a6e85SSai Praneeth Prakhya 	}
318591a6e85SSai Praneeth Prakhya 
319591a6e85SSai Praneeth Prakhya 	return 0;
320591a6e85SSai Praneeth Prakhya }
321591a6e85SSai Praneeth Prakhya 
322591a6e85SSai Praneeth Prakhya /*
323591a6e85SSai Praneeth Prakhya  * create_grp - Create a group only if one doesn't exist
324591a6e85SSai Praneeth Prakhya  * @grp_name:	Name of the group
325591a6e85SSai Praneeth Prakhya  * @grp:	Full path and name of the group
326591a6e85SSai Praneeth Prakhya  * @parent_grp:	Full path and name of the parent group
327591a6e85SSai Praneeth Prakhya  *
32834813938SIlpo Järvinen  * Return: 0 on success, < 0 on error.
329591a6e85SSai Praneeth Prakhya  */
330591a6e85SSai Praneeth Prakhya static int create_grp(const char *grp_name, char *grp, const char *parent_grp)
331591a6e85SSai Praneeth Prakhya {
332591a6e85SSai Praneeth Prakhya 	int found_grp = 0;
333591a6e85SSai Praneeth Prakhya 	struct dirent *ep;
334591a6e85SSai Praneeth Prakhya 	DIR *dp;
335591a6e85SSai Praneeth Prakhya 
33678941183SFenghua Yu 	/*
33778941183SFenghua Yu 	 * At this point, we are guaranteed to have resctrl FS mounted and if
33878941183SFenghua Yu 	 * length of grp_name == 0, it means, user wants to use root con_mon
33978941183SFenghua Yu 	 * grp, so do nothing
34078941183SFenghua Yu 	 */
34178941183SFenghua Yu 	if (strlen(grp_name) == 0)
34278941183SFenghua Yu 		return 0;
34378941183SFenghua Yu 
344591a6e85SSai Praneeth Prakhya 	/* Check if requested grp exists or not */
345591a6e85SSai Praneeth Prakhya 	dp = opendir(parent_grp);
346591a6e85SSai Praneeth Prakhya 	if (dp) {
347591a6e85SSai Praneeth Prakhya 		while ((ep = readdir(dp)) != NULL) {
348591a6e85SSai Praneeth Prakhya 			if (strcmp(ep->d_name, grp_name) == 0)
349591a6e85SSai Praneeth Prakhya 				found_grp = 1;
350591a6e85SSai Praneeth Prakhya 		}
351591a6e85SSai Praneeth Prakhya 		closedir(dp);
352591a6e85SSai Praneeth Prakhya 	} else {
353cc8ff7f5SIlpo Järvinen 		ksft_perror("Unable to open resctrl for group");
354591a6e85SSai Praneeth Prakhya 
355591a6e85SSai Praneeth Prakhya 		return -1;
356591a6e85SSai Praneeth Prakhya 	}
357591a6e85SSai Praneeth Prakhya 
358591a6e85SSai Praneeth Prakhya 	/* Requested grp doesn't exist, hence create it */
359591a6e85SSai Praneeth Prakhya 	if (found_grp == 0) {
360591a6e85SSai Praneeth Prakhya 		if (mkdir(grp, 0) == -1) {
361cc8ff7f5SIlpo Järvinen 			ksft_perror("Unable to create group");
362591a6e85SSai Praneeth Prakhya 
363591a6e85SSai Praneeth Prakhya 			return -1;
364591a6e85SSai Praneeth Prakhya 		}
365591a6e85SSai Praneeth Prakhya 	}
366591a6e85SSai Praneeth Prakhya 
367591a6e85SSai Praneeth Prakhya 	return 0;
368591a6e85SSai Praneeth Prakhya }
369591a6e85SSai Praneeth Prakhya 
370591a6e85SSai Praneeth Prakhya static int write_pid_to_tasks(char *tasks, pid_t pid)
371591a6e85SSai Praneeth Prakhya {
372591a6e85SSai Praneeth Prakhya 	FILE *fp;
373591a6e85SSai Praneeth Prakhya 
374591a6e85SSai Praneeth Prakhya 	fp = fopen(tasks, "w");
375591a6e85SSai Praneeth Prakhya 	if (!fp) {
376cc8ff7f5SIlpo Järvinen 		ksft_perror("Failed to open tasks file");
377591a6e85SSai Praneeth Prakhya 
378591a6e85SSai Praneeth Prakhya 		return -1;
379591a6e85SSai Praneeth Prakhya 	}
380591a6e85SSai Praneeth Prakhya 	if (fprintf(fp, "%d\n", pid) < 0) {
381cc8ff7f5SIlpo Järvinen 		ksft_print_msg("Failed to write pid to tasks file\n");
382591a6e85SSai Praneeth Prakhya 		fclose(fp);
383591a6e85SSai Praneeth Prakhya 
384591a6e85SSai Praneeth Prakhya 		return -1;
385591a6e85SSai Praneeth Prakhya 	}
386591a6e85SSai Praneeth Prakhya 	fclose(fp);
387591a6e85SSai Praneeth Prakhya 
388591a6e85SSai Praneeth Prakhya 	return 0;
389591a6e85SSai Praneeth Prakhya }
390591a6e85SSai Praneeth Prakhya 
391591a6e85SSai Praneeth Prakhya /*
392591a6e85SSai Praneeth Prakhya  * write_bm_pid_to_resctrl - Write a PID (i.e. benchmark) to resctrl FS
393591a6e85SSai Praneeth Prakhya  * @bm_pid:		PID that should be written
394591a6e85SSai Praneeth Prakhya  * @ctrlgrp:		Name of the control monitor group (con_mon grp)
395591a6e85SSai Praneeth Prakhya  * @mongrp:		Name of the monitor group (mon grp)
396591a6e85SSai Praneeth Prakhya  * @resctrl_val:	Resctrl feature (Eg: mbm, mba.. etc)
397591a6e85SSai Praneeth Prakhya  *
398591a6e85SSai Praneeth Prakhya  * If a con_mon grp is requested, create it and write pid to it, otherwise
399591a6e85SSai Praneeth Prakhya  * write pid to root con_mon grp.
400591a6e85SSai Praneeth Prakhya  * If a mon grp is requested, create it and write pid to it, otherwise
401591a6e85SSai Praneeth Prakhya  * pid is not written, this means that pid is in con_mon grp and hence
402591a6e85SSai Praneeth Prakhya  * should consult con_mon grp's mon_data directory for results.
403591a6e85SSai Praneeth Prakhya  *
40434813938SIlpo Järvinen  * Return: 0 on success, < 0 on error.
405591a6e85SSai Praneeth Prakhya  */
406591a6e85SSai Praneeth Prakhya int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
407591a6e85SSai Praneeth Prakhya 			    char *resctrl_val)
408591a6e85SSai Praneeth Prakhya {
409591a6e85SSai Praneeth Prakhya 	char controlgroup[128], monitorgroup[512], monitorgroup_p[256];
410591a6e85SSai Praneeth Prakhya 	char tasks[1024];
411591a6e85SSai Praneeth Prakhya 	int ret = 0;
412591a6e85SSai Praneeth Prakhya 
413591a6e85SSai Praneeth Prakhya 	if (strlen(ctrlgrp))
414591a6e85SSai Praneeth Prakhya 		sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp);
415591a6e85SSai Praneeth Prakhya 	else
416591a6e85SSai Praneeth Prakhya 		sprintf(controlgroup, "%s", RESCTRL_PATH);
417591a6e85SSai Praneeth Prakhya 
418591a6e85SSai Praneeth Prakhya 	/* Create control and monitoring group and write pid into it */
419591a6e85SSai Praneeth Prakhya 	ret = create_grp(ctrlgrp, controlgroup, RESCTRL_PATH);
420591a6e85SSai Praneeth Prakhya 	if (ret)
421591a6e85SSai Praneeth Prakhya 		goto out;
422591a6e85SSai Praneeth Prakhya 	sprintf(tasks, "%s/tasks", controlgroup);
423591a6e85SSai Praneeth Prakhya 	ret = write_pid_to_tasks(tasks, bm_pid);
424591a6e85SSai Praneeth Prakhya 	if (ret)
425591a6e85SSai Praneeth Prakhya 		goto out;
426591a6e85SSai Praneeth Prakhya 
4272f320911SFenghua Yu 	/* Create mon grp and write pid into it for "mbm" and "cmt" test */
4282f320911SFenghua Yu 	if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)) ||
42924286736SFenghua Yu 	    !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
43078941183SFenghua Yu 		if (strlen(mongrp)) {
431591a6e85SSai Praneeth Prakhya 			sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
432591a6e85SSai Praneeth Prakhya 			sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
433591a6e85SSai Praneeth Prakhya 			ret = create_grp(mongrp, monitorgroup, monitorgroup_p);
434591a6e85SSai Praneeth Prakhya 			if (ret)
435591a6e85SSai Praneeth Prakhya 				goto out;
436591a6e85SSai Praneeth Prakhya 
437591a6e85SSai Praneeth Prakhya 			sprintf(tasks, "%s/mon_groups/%s/tasks",
438591a6e85SSai Praneeth Prakhya 				controlgroup, mongrp);
439591a6e85SSai Praneeth Prakhya 			ret = write_pid_to_tasks(tasks, bm_pid);
440591a6e85SSai Praneeth Prakhya 			if (ret)
441591a6e85SSai Praneeth Prakhya 				goto out;
442591a6e85SSai Praneeth Prakhya 		}
443591a6e85SSai Praneeth Prakhya 	}
444591a6e85SSai Praneeth Prakhya 
445591a6e85SSai Praneeth Prakhya out:
446ca2f4214SFenghua Yu 	ksft_print_msg("Writing benchmark parameters to resctrl FS\n");
447591a6e85SSai Praneeth Prakhya 	if (ret)
448cc8ff7f5SIlpo Järvinen 		ksft_print_msg("Failed writing to resctrlfs\n");
449591a6e85SSai Praneeth Prakhya 
450591a6e85SSai Praneeth Prakhya 	return ret;
451591a6e85SSai Praneeth Prakhya }
452591a6e85SSai Praneeth Prakhya 
453591a6e85SSai Praneeth Prakhya /*
454591a6e85SSai Praneeth Prakhya  * write_schemata - Update schemata of a con_mon grp
455591a6e85SSai Praneeth Prakhya  * @ctrlgrp:		Name of the con_mon grp
456591a6e85SSai Praneeth Prakhya  * @schemata:		Schemata that should be updated to
457591a6e85SSai Praneeth Prakhya  * @cpu_no:		CPU number that the benchmark PID is binded to
458591a6e85SSai Praneeth Prakhya  * @resctrl_val:	Resctrl feature (Eg: mbm, mba.. etc)
459591a6e85SSai Praneeth Prakhya  *
460591a6e85SSai Praneeth Prakhya  * Update schemata of a con_mon grp *only* if requested resctrl feature is
461591a6e85SSai Praneeth Prakhya  * allocation type
462591a6e85SSai Praneeth Prakhya  *
46334813938SIlpo Järvinen  * Return: 0 on success, < 0 on error.
464591a6e85SSai Praneeth Prakhya  */
465591a6e85SSai Praneeth Prakhya int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
466591a6e85SSai Praneeth Prakhya {
46720d96b25SMaciej Wieczor-Retman 	char controlgroup[1024], reason[128], schema[1024] = {};
46820d96b25SMaciej Wieczor-Retman 	int resource_id, fd, schema_len = -1, ret = 0;
469591a6e85SSai Praneeth Prakhya 
47024286736SFenghua Yu 	if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
47142e3b093SShaopeng Tan 	    strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) &&
47224286736SFenghua Yu 	    strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
4732f320911SFenghua Yu 	    strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
474591a6e85SSai Praneeth Prakhya 		return -ENOENT;
475591a6e85SSai Praneeth Prakhya 
476591a6e85SSai Praneeth Prakhya 	if (!schemata) {
477ca2f4214SFenghua Yu 		ksft_print_msg("Skipping empty schemata update\n");
478591a6e85SSai Praneeth Prakhya 
479591a6e85SSai Praneeth Prakhya 		return -1;
480591a6e85SSai Praneeth Prakhya 	}
481591a6e85SSai Praneeth Prakhya 
482591a6e85SSai Praneeth Prakhya 	if (get_resource_id(cpu_no, &resource_id) < 0) {
483591a6e85SSai Praneeth Prakhya 		sprintf(reason, "Failed to get resource id");
484591a6e85SSai Praneeth Prakhya 		ret = -1;
485591a6e85SSai Praneeth Prakhya 
486591a6e85SSai Praneeth Prakhya 		goto out;
487591a6e85SSai Praneeth Prakhya 	}
488591a6e85SSai Praneeth Prakhya 
489591a6e85SSai Praneeth Prakhya 	if (strlen(ctrlgrp) != 0)
490591a6e85SSai Praneeth Prakhya 		sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp);
491591a6e85SSai Praneeth Prakhya 	else
492591a6e85SSai Praneeth Prakhya 		sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
493591a6e85SSai Praneeth Prakhya 
49424286736SFenghua Yu 	if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
4952f320911SFenghua Yu 	    !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
49620d96b25SMaciej Wieczor-Retman 		schema_len = snprintf(schema, sizeof(schema), "%s%d%c%s\n",
49720d96b25SMaciej Wieczor-Retman 				      "L3:", resource_id, '=', schemata);
49842e3b093SShaopeng Tan 	if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) ||
49942e3b093SShaopeng Tan 	    !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)))
50020d96b25SMaciej Wieczor-Retman 		schema_len = snprintf(schema, sizeof(schema), "%s%d%c%s\n",
50120d96b25SMaciej Wieczor-Retman 				      "MB:", resource_id, '=', schemata);
50220d96b25SMaciej Wieczor-Retman 	if (schema_len < 0 || schema_len >= sizeof(schema)) {
50320d96b25SMaciej Wieczor-Retman 		snprintf(reason, sizeof(reason),
50420d96b25SMaciej Wieczor-Retman 			 "snprintf() failed with return value : %d", schema_len);
505591a6e85SSai Praneeth Prakhya 		ret = -1;
506591a6e85SSai Praneeth Prakhya 		goto out;
507591a6e85SSai Praneeth Prakhya 	}
508591a6e85SSai Praneeth Prakhya 
50920d96b25SMaciej Wieczor-Retman 	fd = open(controlgroup, O_WRONLY);
51020d96b25SMaciej Wieczor-Retman 	if (fd < 0) {
51120d96b25SMaciej Wieczor-Retman 		snprintf(reason, sizeof(reason),
51220d96b25SMaciej Wieczor-Retman 			 "open() failed : %s", strerror(errno));
513591a6e85SSai Praneeth Prakhya 		ret = -1;
514591a6e85SSai Praneeth Prakhya 
51520d96b25SMaciej Wieczor-Retman 		goto err_schema_not_empty;
516591a6e85SSai Praneeth Prakhya 	}
51720d96b25SMaciej Wieczor-Retman 	if (write(fd, schema, schema_len) < 0) {
51820d96b25SMaciej Wieczor-Retman 		snprintf(reason, sizeof(reason),
51920d96b25SMaciej Wieczor-Retman 			 "write() failed : %s", strerror(errno));
52020d96b25SMaciej Wieczor-Retman 		close(fd);
52120d96b25SMaciej Wieczor-Retman 		ret = -1;
522591a6e85SSai Praneeth Prakhya 
52320d96b25SMaciej Wieczor-Retman 		goto err_schema_not_empty;
52420d96b25SMaciej Wieczor-Retman 	}
52520d96b25SMaciej Wieczor-Retman 	close(fd);
52620d96b25SMaciej Wieczor-Retman 
52720d96b25SMaciej Wieczor-Retman err_schema_not_empty:
52820d96b25SMaciej Wieczor-Retman 	schema[schema_len - 1] = 0;
529591a6e85SSai Praneeth Prakhya out:
530ca2f4214SFenghua Yu 	ksft_print_msg("Write schema \"%s\" to resctrl FS%s%s\n",
531ca2f4214SFenghua Yu 		       schema, ret ? " # " : "",
532591a6e85SSai Praneeth Prakhya 		       ret ? reason : "");
533591a6e85SSai Praneeth Prakhya 
534591a6e85SSai Praneeth Prakhya 	return ret;
535591a6e85SSai Praneeth Prakhya }
536591a6e85SSai Praneeth Prakhya 
537ecdbb911SFenghua Yu bool check_resctrlfs_support(void)
538ecdbb911SFenghua Yu {
539ecdbb911SFenghua Yu 	FILE *inf = fopen("/proc/filesystems", "r");
540ecdbb911SFenghua Yu 	DIR *dp;
541ecdbb911SFenghua Yu 	char *res;
542ecdbb911SFenghua Yu 	bool ret = false;
543ecdbb911SFenghua Yu 
544ecdbb911SFenghua Yu 	if (!inf)
545ecdbb911SFenghua Yu 		return false;
546ecdbb911SFenghua Yu 
547ecdbb911SFenghua Yu 	res = fgrep(inf, "nodev\tresctrl\n");
548ecdbb911SFenghua Yu 
549ecdbb911SFenghua Yu 	if (res) {
550ecdbb911SFenghua Yu 		ret = true;
551ecdbb911SFenghua Yu 		free(res);
552ecdbb911SFenghua Yu 	}
553ecdbb911SFenghua Yu 
554ecdbb911SFenghua Yu 	fclose(inf);
555ecdbb911SFenghua Yu 
556e7507478SFenghua Yu 	ksft_print_msg("%s Check kernel supports resctrl filesystem\n",
557ca2f4214SFenghua Yu 		       ret ? "Pass:" : "Fail:");
558ecdbb911SFenghua Yu 
559a3611fbcSFenghua Yu 	if (!ret)
560a3611fbcSFenghua Yu 		return ret;
561a3611fbcSFenghua Yu 
562ecdbb911SFenghua Yu 	dp = opendir(RESCTRL_PATH);
563e7507478SFenghua Yu 	ksft_print_msg("%s Check resctrl mountpoint \"%s\" exists\n",
564ca2f4214SFenghua Yu 		       dp ? "Pass:" : "Fail:", RESCTRL_PATH);
565ecdbb911SFenghua Yu 	if (dp)
566ecdbb911SFenghua Yu 		closedir(dp);
567ecdbb911SFenghua Yu 
568ca2f4214SFenghua Yu 	ksft_print_msg("resctrl filesystem %s mounted\n",
569ecdbb911SFenghua Yu 		       find_resctrl_mount(NULL) ? "not" : "is");
570ecdbb911SFenghua Yu 
571ecdbb911SFenghua Yu 	return ret;
572ecdbb911SFenghua Yu }
573ecdbb911SFenghua Yu 
574591a6e85SSai Praneeth Prakhya char *fgrep(FILE *inf, const char *str)
575591a6e85SSai Praneeth Prakhya {
576591a6e85SSai Praneeth Prakhya 	char line[256];
577591a6e85SSai Praneeth Prakhya 	int slen = strlen(str);
578591a6e85SSai Praneeth Prakhya 
579591a6e85SSai Praneeth Prakhya 	while (!feof(inf)) {
580591a6e85SSai Praneeth Prakhya 		if (!fgets(line, 256, inf))
581591a6e85SSai Praneeth Prakhya 			break;
582591a6e85SSai Praneeth Prakhya 		if (strncmp(line, str, slen))
583591a6e85SSai Praneeth Prakhya 			continue;
584591a6e85SSai Praneeth Prakhya 
585591a6e85SSai Praneeth Prakhya 		return strdup(line);
586591a6e85SSai Praneeth Prakhya 	}
587591a6e85SSai Praneeth Prakhya 
588591a6e85SSai Praneeth Prakhya 	return NULL;
589591a6e85SSai Praneeth Prakhya }
590591a6e85SSai Praneeth Prakhya 
591591a6e85SSai Praneeth Prakhya /*
592591a6e85SSai Praneeth Prakhya  * validate_resctrl_feature_request - Check if requested feature is valid.
593d56e5da0SIlpo Järvinen  * @resource:	Required resource (e.g., MB, L3, L2, L3_MON, etc.)
594d56e5da0SIlpo Järvinen  * @feature:	Required monitor feature (in mon_features file). Can only be
595d56e5da0SIlpo Järvinen  *		set for L3_MON. Must be NULL for all other resources.
596591a6e85SSai Praneeth Prakhya  *
597d56e5da0SIlpo Järvinen  * Return: True if the resource/feature is supported, else false. False is
598d56e5da0SIlpo Järvinen  *         also returned if resctrl FS is not mounted.
599591a6e85SSai Praneeth Prakhya  */
600d56e5da0SIlpo Järvinen bool validate_resctrl_feature_request(const char *resource, const char *feature)
601591a6e85SSai Praneeth Prakhya {
602d56e5da0SIlpo Järvinen 	char res_path[PATH_MAX];
603ee041568SFenghua Yu 	struct stat statbuf;
604591a6e85SSai Praneeth Prakhya 	char *res;
605ee041568SFenghua Yu 	FILE *inf;
606caddc0fbSIlpo Järvinen 	int ret;
607591a6e85SSai Praneeth Prakhya 
608d56e5da0SIlpo Järvinen 	if (!resource)
609ee041568SFenghua Yu 		return false;
610ee041568SFenghua Yu 
611caddc0fbSIlpo Järvinen 	ret = find_resctrl_mount(NULL);
612caddc0fbSIlpo Järvinen 	if (ret)
613ee041568SFenghua Yu 		return false;
614ee041568SFenghua Yu 
615d56e5da0SIlpo Järvinen 	snprintf(res_path, sizeof(res_path), "%s/%s", INFO_PATH, resource);
616d56e5da0SIlpo Järvinen 
617d56e5da0SIlpo Järvinen 	if (stat(res_path, &statbuf))
618d56e5da0SIlpo Järvinen 		return false;
619d56e5da0SIlpo Järvinen 
620d56e5da0SIlpo Järvinen 	if (!feature)
621ee041568SFenghua Yu 		return true;
622d56e5da0SIlpo Järvinen 
623d56e5da0SIlpo Järvinen 	snprintf(res_path, sizeof(res_path), "%s/%s/mon_features", INFO_PATH, resource);
624d56e5da0SIlpo Järvinen 	inf = fopen(res_path, "r");
625591a6e85SSai Praneeth Prakhya 	if (!inf)
626591a6e85SSai Praneeth Prakhya 		return false;
627591a6e85SSai Praneeth Prakhya 
628d56e5da0SIlpo Järvinen 	res = fgrep(inf, feature);
629591a6e85SSai Praneeth Prakhya 	free(res);
630591a6e85SSai Praneeth Prakhya 	fclose(inf);
631591a6e85SSai Praneeth Prakhya 
632d56e5da0SIlpo Järvinen 	return !!res;
633591a6e85SSai Praneeth Prakhya }
634591a6e85SSai Praneeth Prakhya 
635ecdbb911SFenghua Yu int filter_dmesg(void)
636ecdbb911SFenghua Yu {
637ecdbb911SFenghua Yu 	char line[1024];
638ecdbb911SFenghua Yu 	FILE *fp;
639ecdbb911SFenghua Yu 	int pipefds[2];
640ecdbb911SFenghua Yu 	pid_t pid;
641ecdbb911SFenghua Yu 	int ret;
642ecdbb911SFenghua Yu 
643ecdbb911SFenghua Yu 	ret = pipe(pipefds);
644ecdbb911SFenghua Yu 	if (ret) {
645cc8ff7f5SIlpo Järvinen 		ksft_perror("pipe");
646ecdbb911SFenghua Yu 		return ret;
647ecdbb911SFenghua Yu 	}
648a080b6e7SShaopeng Tan 	fflush(stdout);
649ecdbb911SFenghua Yu 	pid = fork();
650ecdbb911SFenghua Yu 	if (pid == 0) {
651ecdbb911SFenghua Yu 		close(pipefds[0]);
652ecdbb911SFenghua Yu 		dup2(pipefds[1], STDOUT_FILENO);
653ecdbb911SFenghua Yu 		execlp("dmesg", "dmesg", NULL);
654cc8ff7f5SIlpo Järvinen 		ksft_perror("Executing dmesg");
655ecdbb911SFenghua Yu 		exit(1);
656ecdbb911SFenghua Yu 	}
657ecdbb911SFenghua Yu 	close(pipefds[1]);
658ecdbb911SFenghua Yu 	fp = fdopen(pipefds[0], "r");
659ecdbb911SFenghua Yu 	if (!fp) {
660cc8ff7f5SIlpo Järvinen 		ksft_perror("fdopen(pipe)");
661ecdbb911SFenghua Yu 		kill(pid, SIGTERM);
662ecdbb911SFenghua Yu 
663ecdbb911SFenghua Yu 		return -1;
664ecdbb911SFenghua Yu 	}
665ecdbb911SFenghua Yu 
666ecdbb911SFenghua Yu 	while (fgets(line, 1024, fp)) {
667ecdbb911SFenghua Yu 		if (strstr(line, "intel_rdt:"))
668ca2f4214SFenghua Yu 			ksft_print_msg("dmesg: %s", line);
669ecdbb911SFenghua Yu 		if (strstr(line, "resctrl:"))
670ca2f4214SFenghua Yu 			ksft_print_msg("dmesg: %s", line);
671ecdbb911SFenghua Yu 	}
672ecdbb911SFenghua Yu 	fclose(fp);
673ecdbb911SFenghua Yu 	waitpid(pid, NULL, 0);
674ecdbb911SFenghua Yu 
675ecdbb911SFenghua Yu 	return 0;
676ecdbb911SFenghua Yu }
677ecdbb911SFenghua Yu 
678591a6e85SSai Praneeth Prakhya int validate_bw_report_request(char *bw_report)
679591a6e85SSai Praneeth Prakhya {
680591a6e85SSai Praneeth Prakhya 	if (strcmp(bw_report, "reads") == 0)
681591a6e85SSai Praneeth Prakhya 		return 0;
682591a6e85SSai Praneeth Prakhya 	if (strcmp(bw_report, "writes") == 0)
683591a6e85SSai Praneeth Prakhya 		return 0;
684591a6e85SSai Praneeth Prakhya 	if (strcmp(bw_report, "nt-writes") == 0) {
685591a6e85SSai Praneeth Prakhya 		strcpy(bw_report, "writes");
686591a6e85SSai Praneeth Prakhya 		return 0;
687591a6e85SSai Praneeth Prakhya 	}
688591a6e85SSai Praneeth Prakhya 	if (strcmp(bw_report, "total") == 0)
689591a6e85SSai Praneeth Prakhya 		return 0;
690591a6e85SSai Praneeth Prakhya 
691591a6e85SSai Praneeth Prakhya 	fprintf(stderr, "Requested iMC B/W report type unavailable\n");
692591a6e85SSai Praneeth Prakhya 
693591a6e85SSai Praneeth Prakhya 	return -1;
694591a6e85SSai Praneeth Prakhya }
695591a6e85SSai Praneeth Prakhya 
696591a6e85SSai Praneeth Prakhya int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
697591a6e85SSai Praneeth Prakhya 		    int group_fd, unsigned long flags)
698591a6e85SSai Praneeth Prakhya {
699591a6e85SSai Praneeth Prakhya 	int ret;
700591a6e85SSai Praneeth Prakhya 
701591a6e85SSai Praneeth Prakhya 	ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
702591a6e85SSai Praneeth Prakhya 		      group_fd, flags);
703591a6e85SSai Praneeth Prakhya 	return ret;
704591a6e85SSai Praneeth Prakhya }
70578941183SFenghua Yu 
70678941183SFenghua Yu unsigned int count_bits(unsigned long n)
70778941183SFenghua Yu {
70878941183SFenghua Yu 	unsigned int count = 0;
70978941183SFenghua Yu 
71078941183SFenghua Yu 	while (n) {
71178941183SFenghua Yu 		count += n & 1;
71278941183SFenghua Yu 		n >>= 1;
71378941183SFenghua Yu 	}
71478941183SFenghua Yu 
71578941183SFenghua Yu 	return count;
71678941183SFenghua Yu }
717