xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/resctrl/resctrlfs.c (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
1*053f45beSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*053f45beSAndroid Build Coastguard Worker /*
3*053f45beSAndroid Build Coastguard Worker  * Basic resctrl file system operations
4*053f45beSAndroid Build Coastguard Worker  *
5*053f45beSAndroid Build Coastguard Worker  * Copyright (C) 2018 Intel Corporation
6*053f45beSAndroid Build Coastguard Worker  *
7*053f45beSAndroid Build Coastguard Worker  * Authors:
8*053f45beSAndroid Build Coastguard Worker  *    Sai Praneeth Prakhya <[email protected]>,
9*053f45beSAndroid Build Coastguard Worker  *    Fenghua Yu <[email protected]>
10*053f45beSAndroid Build Coastguard Worker  */
11*053f45beSAndroid Build Coastguard Worker #include "resctrl.h"
12*053f45beSAndroid Build Coastguard Worker 
find_resctrl_mount(char * buffer)13*053f45beSAndroid Build Coastguard Worker static int find_resctrl_mount(char *buffer)
14*053f45beSAndroid Build Coastguard Worker {
15*053f45beSAndroid Build Coastguard Worker 	FILE *mounts;
16*053f45beSAndroid Build Coastguard Worker 	char line[256], *fs, *mntpoint;
17*053f45beSAndroid Build Coastguard Worker 
18*053f45beSAndroid Build Coastguard Worker 	mounts = fopen("/proc/mounts", "r");
19*053f45beSAndroid Build Coastguard Worker 	if (!mounts) {
20*053f45beSAndroid Build Coastguard Worker 		perror("/proc/mounts");
21*053f45beSAndroid Build Coastguard Worker 		return -ENXIO;
22*053f45beSAndroid Build Coastguard Worker 	}
23*053f45beSAndroid Build Coastguard Worker 	while (!feof(mounts)) {
24*053f45beSAndroid Build Coastguard Worker 		if (!fgets(line, 256, mounts))
25*053f45beSAndroid Build Coastguard Worker 			break;
26*053f45beSAndroid Build Coastguard Worker 		fs = strtok(line, " \t");
27*053f45beSAndroid Build Coastguard Worker 		if (!fs)
28*053f45beSAndroid Build Coastguard Worker 			continue;
29*053f45beSAndroid Build Coastguard Worker 		mntpoint = strtok(NULL, " \t");
30*053f45beSAndroid Build Coastguard Worker 		if (!mntpoint)
31*053f45beSAndroid Build Coastguard Worker 			continue;
32*053f45beSAndroid Build Coastguard Worker 		fs = strtok(NULL, " \t");
33*053f45beSAndroid Build Coastguard Worker 		if (!fs)
34*053f45beSAndroid Build Coastguard Worker 			continue;
35*053f45beSAndroid Build Coastguard Worker 		if (strcmp(fs, "resctrl"))
36*053f45beSAndroid Build Coastguard Worker 			continue;
37*053f45beSAndroid Build Coastguard Worker 
38*053f45beSAndroid Build Coastguard Worker 		fclose(mounts);
39*053f45beSAndroid Build Coastguard Worker 		if (buffer)
40*053f45beSAndroid Build Coastguard Worker 			strncpy(buffer, mntpoint, 256);
41*053f45beSAndroid Build Coastguard Worker 
42*053f45beSAndroid Build Coastguard Worker 		return 0;
43*053f45beSAndroid Build Coastguard Worker 	}
44*053f45beSAndroid Build Coastguard Worker 
45*053f45beSAndroid Build Coastguard Worker 	fclose(mounts);
46*053f45beSAndroid Build Coastguard Worker 
47*053f45beSAndroid Build Coastguard Worker 	return -ENOENT;
48*053f45beSAndroid Build Coastguard Worker }
49*053f45beSAndroid Build Coastguard Worker 
50*053f45beSAndroid Build Coastguard Worker /*
51*053f45beSAndroid Build Coastguard Worker  * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl
52*053f45beSAndroid Build Coastguard Worker  * @mum_resctrlfs:	Should the resctrl FS be remounted?
53*053f45beSAndroid Build Coastguard Worker  *
54*053f45beSAndroid Build Coastguard Worker  * If not mounted, mount it.
55*053f45beSAndroid Build Coastguard Worker  * If mounted and mum_resctrlfs then remount resctrl FS.
56*053f45beSAndroid Build Coastguard Worker  * If mounted and !mum_resctrlfs then noop
57*053f45beSAndroid Build Coastguard Worker  *
58*053f45beSAndroid Build Coastguard Worker  * Return: 0 on success, non-zero on failure
59*053f45beSAndroid Build Coastguard Worker  */
remount_resctrlfs(bool mum_resctrlfs)60*053f45beSAndroid Build Coastguard Worker int remount_resctrlfs(bool mum_resctrlfs)
61*053f45beSAndroid Build Coastguard Worker {
62*053f45beSAndroid Build Coastguard Worker 	char mountpoint[256];
63*053f45beSAndroid Build Coastguard Worker 	int ret;
64*053f45beSAndroid Build Coastguard Worker 
65*053f45beSAndroid Build Coastguard Worker 	ret = find_resctrl_mount(mountpoint);
66*053f45beSAndroid Build Coastguard Worker 	if (ret)
67*053f45beSAndroid Build Coastguard Worker 		strcpy(mountpoint, RESCTRL_PATH);
68*053f45beSAndroid Build Coastguard Worker 
69*053f45beSAndroid Build Coastguard Worker 	if (!ret && mum_resctrlfs && umount(mountpoint))
70*053f45beSAndroid Build Coastguard Worker 		ksft_print_msg("Fail: unmounting \"%s\"\n", mountpoint);
71*053f45beSAndroid Build Coastguard Worker 
72*053f45beSAndroid Build Coastguard Worker 	if (!ret && !mum_resctrlfs)
73*053f45beSAndroid Build Coastguard Worker 		return 0;
74*053f45beSAndroid Build Coastguard Worker 
75*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH);
76*053f45beSAndroid Build Coastguard Worker 	ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL);
77*053f45beSAndroid Build Coastguard Worker 	if (ret)
78*053f45beSAndroid Build Coastguard Worker 		perror("# mount");
79*053f45beSAndroid Build Coastguard Worker 
80*053f45beSAndroid Build Coastguard Worker 	return ret;
81*053f45beSAndroid Build Coastguard Worker }
82*053f45beSAndroid Build Coastguard Worker 
umount_resctrlfs(void)83*053f45beSAndroid Build Coastguard Worker int umount_resctrlfs(void)
84*053f45beSAndroid Build Coastguard Worker {
85*053f45beSAndroid Build Coastguard Worker 	if (find_resctrl_mount(NULL))
86*053f45beSAndroid Build Coastguard Worker 		return 0;
87*053f45beSAndroid Build Coastguard Worker 
88*053f45beSAndroid Build Coastguard Worker 	if (umount(RESCTRL_PATH)) {
89*053f45beSAndroid Build Coastguard Worker 		perror("# Unable to umount resctrl");
90*053f45beSAndroid Build Coastguard Worker 
91*053f45beSAndroid Build Coastguard Worker 		return errno;
92*053f45beSAndroid Build Coastguard Worker 	}
93*053f45beSAndroid Build Coastguard Worker 
94*053f45beSAndroid Build Coastguard Worker 	return 0;
95*053f45beSAndroid Build Coastguard Worker }
96*053f45beSAndroid Build Coastguard Worker 
97*053f45beSAndroid Build Coastguard Worker /*
98*053f45beSAndroid Build Coastguard Worker  * get_resource_id - Get socket number/l3 id for a specified CPU
99*053f45beSAndroid Build Coastguard Worker  * @cpu_no:	CPU number
100*053f45beSAndroid Build Coastguard Worker  * @resource_id: Socket number or l3_id
101*053f45beSAndroid Build Coastguard Worker  *
102*053f45beSAndroid Build Coastguard Worker  * Return: >= 0 on success, < 0 on failure.
103*053f45beSAndroid Build Coastguard Worker  */
get_resource_id(int cpu_no,int * resource_id)104*053f45beSAndroid Build Coastguard Worker int get_resource_id(int cpu_no, int *resource_id)
105*053f45beSAndroid Build Coastguard Worker {
106*053f45beSAndroid Build Coastguard Worker 	char phys_pkg_path[1024];
107*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
108*053f45beSAndroid Build Coastguard Worker 
109*053f45beSAndroid Build Coastguard Worker 	if (get_vendor() == ARCH_AMD)
110*053f45beSAndroid Build Coastguard Worker 		sprintf(phys_pkg_path, "%s%d/cache/index3/id",
111*053f45beSAndroid Build Coastguard Worker 			PHYS_ID_PATH, cpu_no);
112*053f45beSAndroid Build Coastguard Worker 	else
113*053f45beSAndroid Build Coastguard Worker 		sprintf(phys_pkg_path, "%s%d/topology/physical_package_id",
114*053f45beSAndroid Build Coastguard Worker 			PHYS_ID_PATH, cpu_no);
115*053f45beSAndroid Build Coastguard Worker 
116*053f45beSAndroid Build Coastguard Worker 	fp = fopen(phys_pkg_path, "r");
117*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
118*053f45beSAndroid Build Coastguard Worker 		perror("Failed to open physical_package_id");
119*053f45beSAndroid Build Coastguard Worker 
120*053f45beSAndroid Build Coastguard Worker 		return -1;
121*053f45beSAndroid Build Coastguard Worker 	}
122*053f45beSAndroid Build Coastguard Worker 	if (fscanf(fp, "%d", resource_id) <= 0) {
123*053f45beSAndroid Build Coastguard Worker 		perror("Could not get socket number or l3 id");
124*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
125*053f45beSAndroid Build Coastguard Worker 
126*053f45beSAndroid Build Coastguard Worker 		return -1;
127*053f45beSAndroid Build Coastguard Worker 	}
128*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
129*053f45beSAndroid Build Coastguard Worker 
130*053f45beSAndroid Build Coastguard Worker 	return 0;
131*053f45beSAndroid Build Coastguard Worker }
132*053f45beSAndroid Build Coastguard Worker 
133*053f45beSAndroid Build Coastguard Worker /*
134*053f45beSAndroid Build Coastguard Worker  * get_cache_size - Get cache size for a specified CPU
135*053f45beSAndroid Build Coastguard Worker  * @cpu_no:	CPU number
136*053f45beSAndroid Build Coastguard Worker  * @cache_type:	Cache level L2/L3
137*053f45beSAndroid Build Coastguard Worker  * @cache_size:	pointer to cache_size
138*053f45beSAndroid Build Coastguard Worker  *
139*053f45beSAndroid Build Coastguard Worker  * Return: = 0 on success, < 0 on failure.
140*053f45beSAndroid Build Coastguard Worker  */
get_cache_size(int cpu_no,char * cache_type,unsigned long * cache_size)141*053f45beSAndroid Build Coastguard Worker int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size)
142*053f45beSAndroid Build Coastguard Worker {
143*053f45beSAndroid Build Coastguard Worker 	char cache_path[1024], cache_str[64];
144*053f45beSAndroid Build Coastguard Worker 	int length, i, cache_num;
145*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
146*053f45beSAndroid Build Coastguard Worker 
147*053f45beSAndroid Build Coastguard Worker 	if (!strcmp(cache_type, "L3")) {
148*053f45beSAndroid Build Coastguard Worker 		cache_num = 3;
149*053f45beSAndroid Build Coastguard Worker 	} else if (!strcmp(cache_type, "L2")) {
150*053f45beSAndroid Build Coastguard Worker 		cache_num = 2;
151*053f45beSAndroid Build Coastguard Worker 	} else {
152*053f45beSAndroid Build Coastguard Worker 		perror("Invalid cache level");
153*053f45beSAndroid Build Coastguard Worker 		return -1;
154*053f45beSAndroid Build Coastguard Worker 	}
155*053f45beSAndroid Build Coastguard Worker 
156*053f45beSAndroid Build Coastguard Worker 	sprintf(cache_path, "/sys/bus/cpu/devices/cpu%d/cache/index%d/size",
157*053f45beSAndroid Build Coastguard Worker 		cpu_no, cache_num);
158*053f45beSAndroid Build Coastguard Worker 	fp = fopen(cache_path, "r");
159*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
160*053f45beSAndroid Build Coastguard Worker 		perror("Failed to open cache size");
161*053f45beSAndroid Build Coastguard Worker 
162*053f45beSAndroid Build Coastguard Worker 		return -1;
163*053f45beSAndroid Build Coastguard Worker 	}
164*053f45beSAndroid Build Coastguard Worker 	if (fscanf(fp, "%s", cache_str) <= 0) {
165*053f45beSAndroid Build Coastguard Worker 		perror("Could not get cache_size");
166*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
167*053f45beSAndroid Build Coastguard Worker 
168*053f45beSAndroid Build Coastguard Worker 		return -1;
169*053f45beSAndroid Build Coastguard Worker 	}
170*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
171*053f45beSAndroid Build Coastguard Worker 
172*053f45beSAndroid Build Coastguard Worker 	length = (int)strlen(cache_str);
173*053f45beSAndroid Build Coastguard Worker 
174*053f45beSAndroid Build Coastguard Worker 	*cache_size = 0;
175*053f45beSAndroid Build Coastguard Worker 
176*053f45beSAndroid Build Coastguard Worker 	for (i = 0; i < length; i++) {
177*053f45beSAndroid Build Coastguard Worker 		if ((cache_str[i] >= '0') && (cache_str[i] <= '9'))
178*053f45beSAndroid Build Coastguard Worker 
179*053f45beSAndroid Build Coastguard Worker 			*cache_size = *cache_size * 10 + (cache_str[i] - '0');
180*053f45beSAndroid Build Coastguard Worker 
181*053f45beSAndroid Build Coastguard Worker 		else if (cache_str[i] == 'K')
182*053f45beSAndroid Build Coastguard Worker 
183*053f45beSAndroid Build Coastguard Worker 			*cache_size = *cache_size * 1024;
184*053f45beSAndroid Build Coastguard Worker 
185*053f45beSAndroid Build Coastguard Worker 		else if (cache_str[i] == 'M')
186*053f45beSAndroid Build Coastguard Worker 
187*053f45beSAndroid Build Coastguard Worker 			*cache_size = *cache_size * 1024 * 1024;
188*053f45beSAndroid Build Coastguard Worker 
189*053f45beSAndroid Build Coastguard Worker 		else
190*053f45beSAndroid Build Coastguard Worker 			break;
191*053f45beSAndroid Build Coastguard Worker 	}
192*053f45beSAndroid Build Coastguard Worker 
193*053f45beSAndroid Build Coastguard Worker 	return 0;
194*053f45beSAndroid Build Coastguard Worker }
195*053f45beSAndroid Build Coastguard Worker 
196*053f45beSAndroid Build Coastguard Worker #define CORE_SIBLINGS_PATH	"/sys/bus/cpu/devices/cpu"
197*053f45beSAndroid Build Coastguard Worker 
198*053f45beSAndroid Build Coastguard Worker /*
199*053f45beSAndroid Build Coastguard Worker  * get_cbm_mask - Get cbm mask for given cache
200*053f45beSAndroid Build Coastguard Worker  * @cache_type:	Cache level L2/L3
201*053f45beSAndroid Build Coastguard Worker  * @cbm_mask:	cbm_mask returned as a string
202*053f45beSAndroid Build Coastguard Worker  *
203*053f45beSAndroid Build Coastguard Worker  * Return: = 0 on success, < 0 on failure.
204*053f45beSAndroid Build Coastguard Worker  */
get_cbm_mask(char * cache_type,char * cbm_mask)205*053f45beSAndroid Build Coastguard Worker int get_cbm_mask(char *cache_type, char *cbm_mask)
206*053f45beSAndroid Build Coastguard Worker {
207*053f45beSAndroid Build Coastguard Worker 	char cbm_mask_path[1024];
208*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
209*053f45beSAndroid Build Coastguard Worker 
210*053f45beSAndroid Build Coastguard Worker 	if (!cbm_mask)
211*053f45beSAndroid Build Coastguard Worker 		return -1;
212*053f45beSAndroid Build Coastguard Worker 
213*053f45beSAndroid Build Coastguard Worker 	sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type);
214*053f45beSAndroid Build Coastguard Worker 
215*053f45beSAndroid Build Coastguard Worker 	fp = fopen(cbm_mask_path, "r");
216*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
217*053f45beSAndroid Build Coastguard Worker 		perror("Failed to open cache level");
218*053f45beSAndroid Build Coastguard Worker 
219*053f45beSAndroid Build Coastguard Worker 		return -1;
220*053f45beSAndroid Build Coastguard Worker 	}
221*053f45beSAndroid Build Coastguard Worker 	if (fscanf(fp, "%s", cbm_mask) <= 0) {
222*053f45beSAndroid Build Coastguard Worker 		perror("Could not get max cbm_mask");
223*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
224*053f45beSAndroid Build Coastguard Worker 
225*053f45beSAndroid Build Coastguard Worker 		return -1;
226*053f45beSAndroid Build Coastguard Worker 	}
227*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
228*053f45beSAndroid Build Coastguard Worker 
229*053f45beSAndroid Build Coastguard Worker 	return 0;
230*053f45beSAndroid Build Coastguard Worker }
231*053f45beSAndroid Build Coastguard Worker 
232*053f45beSAndroid Build Coastguard Worker /*
233*053f45beSAndroid Build Coastguard Worker  * get_core_sibling - Get sibling core id from the same socket for given CPU
234*053f45beSAndroid Build Coastguard Worker  * @cpu_no:	CPU number
235*053f45beSAndroid Build Coastguard Worker  *
236*053f45beSAndroid Build Coastguard Worker  * Return:	> 0 on success, < 0 on failure.
237*053f45beSAndroid Build Coastguard Worker  */
get_core_sibling(int cpu_no)238*053f45beSAndroid Build Coastguard Worker int get_core_sibling(int cpu_no)
239*053f45beSAndroid Build Coastguard Worker {
240*053f45beSAndroid Build Coastguard Worker 	char core_siblings_path[1024], cpu_list_str[64];
241*053f45beSAndroid Build Coastguard Worker 	int sibling_cpu_no = -1;
242*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
243*053f45beSAndroid Build Coastguard Worker 
244*053f45beSAndroid Build Coastguard Worker 	sprintf(core_siblings_path, "%s%d/topology/core_siblings_list",
245*053f45beSAndroid Build Coastguard Worker 		CORE_SIBLINGS_PATH, cpu_no);
246*053f45beSAndroid Build Coastguard Worker 
247*053f45beSAndroid Build Coastguard Worker 	fp = fopen(core_siblings_path, "r");
248*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
249*053f45beSAndroid Build Coastguard Worker 		perror("Failed to open core siblings path");
250*053f45beSAndroid Build Coastguard Worker 
251*053f45beSAndroid Build Coastguard Worker 		return -1;
252*053f45beSAndroid Build Coastguard Worker 	}
253*053f45beSAndroid Build Coastguard Worker 	if (fscanf(fp, "%s", cpu_list_str) <= 0) {
254*053f45beSAndroid Build Coastguard Worker 		perror("Could not get core_siblings list");
255*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
256*053f45beSAndroid Build Coastguard Worker 
257*053f45beSAndroid Build Coastguard Worker 		return -1;
258*053f45beSAndroid Build Coastguard Worker 	}
259*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
260*053f45beSAndroid Build Coastguard Worker 
261*053f45beSAndroid Build Coastguard Worker 	char *token = strtok(cpu_list_str, "-,");
262*053f45beSAndroid Build Coastguard Worker 
263*053f45beSAndroid Build Coastguard Worker 	while (token) {
264*053f45beSAndroid Build Coastguard Worker 		sibling_cpu_no = atoi(token);
265*053f45beSAndroid Build Coastguard Worker 		/* Skipping core 0 as we don't want to run test on core 0 */
266*053f45beSAndroid Build Coastguard Worker 		if (sibling_cpu_no != 0 && sibling_cpu_no != cpu_no)
267*053f45beSAndroid Build Coastguard Worker 			break;
268*053f45beSAndroid Build Coastguard Worker 		token = strtok(NULL, "-,");
269*053f45beSAndroid Build Coastguard Worker 	}
270*053f45beSAndroid Build Coastguard Worker 
271*053f45beSAndroid Build Coastguard Worker 	return sibling_cpu_no;
272*053f45beSAndroid Build Coastguard Worker }
273*053f45beSAndroid Build Coastguard Worker 
274*053f45beSAndroid Build Coastguard Worker /*
275*053f45beSAndroid Build Coastguard Worker  * taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu
276*053f45beSAndroid Build Coastguard Worker  * @bm_pid:	PID that should be binded
277*053f45beSAndroid Build Coastguard Worker  * @cpu_no:	CPU number at which the PID would be binded
278*053f45beSAndroid Build Coastguard Worker  *
279*053f45beSAndroid Build Coastguard Worker  * Return: 0 on success, non-zero on failure
280*053f45beSAndroid Build Coastguard Worker  */
taskset_benchmark(pid_t bm_pid,int cpu_no)281*053f45beSAndroid Build Coastguard Worker int taskset_benchmark(pid_t bm_pid, int cpu_no)
282*053f45beSAndroid Build Coastguard Worker {
283*053f45beSAndroid Build Coastguard Worker 	cpu_set_t my_set;
284*053f45beSAndroid Build Coastguard Worker 
285*053f45beSAndroid Build Coastguard Worker 	CPU_ZERO(&my_set);
286*053f45beSAndroid Build Coastguard Worker 	CPU_SET(cpu_no, &my_set);
287*053f45beSAndroid Build Coastguard Worker 
288*053f45beSAndroid Build Coastguard Worker 	if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) {
289*053f45beSAndroid Build Coastguard Worker 		perror("Unable to taskset benchmark");
290*053f45beSAndroid Build Coastguard Worker 
291*053f45beSAndroid Build Coastguard Worker 		return -1;
292*053f45beSAndroid Build Coastguard Worker 	}
293*053f45beSAndroid Build Coastguard Worker 
294*053f45beSAndroid Build Coastguard Worker 	return 0;
295*053f45beSAndroid Build Coastguard Worker }
296*053f45beSAndroid Build Coastguard Worker 
297*053f45beSAndroid Build Coastguard Worker /*
298*053f45beSAndroid Build Coastguard Worker  * run_benchmark - Run a specified benchmark or fill_buf (default benchmark)
299*053f45beSAndroid Build Coastguard Worker  *		   in specified signal. Direct benchmark stdio to /dev/null.
300*053f45beSAndroid Build Coastguard Worker  * @signum:	signal number
301*053f45beSAndroid Build Coastguard Worker  * @info:	signal info
302*053f45beSAndroid Build Coastguard Worker  * @ucontext:	user context in signal handling
303*053f45beSAndroid Build Coastguard Worker  *
304*053f45beSAndroid Build Coastguard Worker  * Return: void
305*053f45beSAndroid Build Coastguard Worker  */
run_benchmark(int signum,siginfo_t * info,void * ucontext)306*053f45beSAndroid Build Coastguard Worker void run_benchmark(int signum, siginfo_t *info, void *ucontext)
307*053f45beSAndroid Build Coastguard Worker {
308*053f45beSAndroid Build Coastguard Worker 	int operation, ret, malloc_and_init_memory, memflush;
309*053f45beSAndroid Build Coastguard Worker 	unsigned long span, buffer_span;
310*053f45beSAndroid Build Coastguard Worker 	char **benchmark_cmd;
311*053f45beSAndroid Build Coastguard Worker 	char resctrl_val[64];
312*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
313*053f45beSAndroid Build Coastguard Worker 
314*053f45beSAndroid Build Coastguard Worker 	benchmark_cmd = info->si_ptr;
315*053f45beSAndroid Build Coastguard Worker 
316*053f45beSAndroid Build Coastguard Worker 	/*
317*053f45beSAndroid Build Coastguard Worker 	 * Direct stdio of child to /dev/null, so that only parent writes to
318*053f45beSAndroid Build Coastguard Worker 	 * stdio (console)
319*053f45beSAndroid Build Coastguard Worker 	 */
320*053f45beSAndroid Build Coastguard Worker 	fp = freopen("/dev/null", "w", stdout);
321*053f45beSAndroid Build Coastguard Worker 	if (!fp)
322*053f45beSAndroid Build Coastguard Worker 		PARENT_EXIT("Unable to direct benchmark status to /dev/null");
323*053f45beSAndroid Build Coastguard Worker 
324*053f45beSAndroid Build Coastguard Worker 	if (strcmp(benchmark_cmd[0], "fill_buf") == 0) {
325*053f45beSAndroid Build Coastguard Worker 		/* Execute default fill_buf benchmark */
326*053f45beSAndroid Build Coastguard Worker 		span = strtoul(benchmark_cmd[1], NULL, 10);
327*053f45beSAndroid Build Coastguard Worker 		malloc_and_init_memory = atoi(benchmark_cmd[2]);
328*053f45beSAndroid Build Coastguard Worker 		memflush =  atoi(benchmark_cmd[3]);
329*053f45beSAndroid Build Coastguard Worker 		operation = atoi(benchmark_cmd[4]);
330*053f45beSAndroid Build Coastguard Worker 		sprintf(resctrl_val, "%s", benchmark_cmd[5]);
331*053f45beSAndroid Build Coastguard Worker 
332*053f45beSAndroid Build Coastguard Worker 		if (strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
333*053f45beSAndroid Build Coastguard Worker 			buffer_span = span * MB;
334*053f45beSAndroid Build Coastguard Worker 		else
335*053f45beSAndroid Build Coastguard Worker 			buffer_span = span;
336*053f45beSAndroid Build Coastguard Worker 
337*053f45beSAndroid Build Coastguard Worker 		if (run_fill_buf(buffer_span, malloc_and_init_memory, memflush,
338*053f45beSAndroid Build Coastguard Worker 				 operation, resctrl_val))
339*053f45beSAndroid Build Coastguard Worker 			fprintf(stderr, "Error in running fill buffer\n");
340*053f45beSAndroid Build Coastguard Worker 	} else {
341*053f45beSAndroid Build Coastguard Worker 		/* Execute specified benchmark */
342*053f45beSAndroid Build Coastguard Worker 		ret = execvp(benchmark_cmd[0], benchmark_cmd);
343*053f45beSAndroid Build Coastguard Worker 		if (ret)
344*053f45beSAndroid Build Coastguard Worker 			perror("wrong\n");
345*053f45beSAndroid Build Coastguard Worker 	}
346*053f45beSAndroid Build Coastguard Worker 
347*053f45beSAndroid Build Coastguard Worker 	fclose(stdout);
348*053f45beSAndroid Build Coastguard Worker 	PARENT_EXIT("Unable to run specified benchmark");
349*053f45beSAndroid Build Coastguard Worker }
350*053f45beSAndroid Build Coastguard Worker 
351*053f45beSAndroid Build Coastguard Worker /*
352*053f45beSAndroid Build Coastguard Worker  * create_grp - Create a group only if one doesn't exist
353*053f45beSAndroid Build Coastguard Worker  * @grp_name:	Name of the group
354*053f45beSAndroid Build Coastguard Worker  * @grp:	Full path and name of the group
355*053f45beSAndroid Build Coastguard Worker  * @parent_grp:	Full path and name of the parent group
356*053f45beSAndroid Build Coastguard Worker  *
357*053f45beSAndroid Build Coastguard Worker  * Return: 0 on success, non-zero on failure
358*053f45beSAndroid Build Coastguard Worker  */
create_grp(const char * grp_name,char * grp,const char * parent_grp)359*053f45beSAndroid Build Coastguard Worker static int create_grp(const char *grp_name, char *grp, const char *parent_grp)
360*053f45beSAndroid Build Coastguard Worker {
361*053f45beSAndroid Build Coastguard Worker 	int found_grp = 0;
362*053f45beSAndroid Build Coastguard Worker 	struct dirent *ep;
363*053f45beSAndroid Build Coastguard Worker 	DIR *dp;
364*053f45beSAndroid Build Coastguard Worker 
365*053f45beSAndroid Build Coastguard Worker 	/*
366*053f45beSAndroid Build Coastguard Worker 	 * At this point, we are guaranteed to have resctrl FS mounted and if
367*053f45beSAndroid Build Coastguard Worker 	 * length of grp_name == 0, it means, user wants to use root con_mon
368*053f45beSAndroid Build Coastguard Worker 	 * grp, so do nothing
369*053f45beSAndroid Build Coastguard Worker 	 */
370*053f45beSAndroid Build Coastguard Worker 	if (strlen(grp_name) == 0)
371*053f45beSAndroid Build Coastguard Worker 		return 0;
372*053f45beSAndroid Build Coastguard Worker 
373*053f45beSAndroid Build Coastguard Worker 	/* Check if requested grp exists or not */
374*053f45beSAndroid Build Coastguard Worker 	dp = opendir(parent_grp);
375*053f45beSAndroid Build Coastguard Worker 	if (dp) {
376*053f45beSAndroid Build Coastguard Worker 		while ((ep = readdir(dp)) != NULL) {
377*053f45beSAndroid Build Coastguard Worker 			if (strcmp(ep->d_name, grp_name) == 0)
378*053f45beSAndroid Build Coastguard Worker 				found_grp = 1;
379*053f45beSAndroid Build Coastguard Worker 		}
380*053f45beSAndroid Build Coastguard Worker 		closedir(dp);
381*053f45beSAndroid Build Coastguard Worker 	} else {
382*053f45beSAndroid Build Coastguard Worker 		perror("Unable to open resctrl for group");
383*053f45beSAndroid Build Coastguard Worker 
384*053f45beSAndroid Build Coastguard Worker 		return -1;
385*053f45beSAndroid Build Coastguard Worker 	}
386*053f45beSAndroid Build Coastguard Worker 
387*053f45beSAndroid Build Coastguard Worker 	/* Requested grp doesn't exist, hence create it */
388*053f45beSAndroid Build Coastguard Worker 	if (found_grp == 0) {
389*053f45beSAndroid Build Coastguard Worker 		if (mkdir(grp, 0) == -1) {
390*053f45beSAndroid Build Coastguard Worker 			perror("Unable to create group");
391*053f45beSAndroid Build Coastguard Worker 
392*053f45beSAndroid Build Coastguard Worker 			return -1;
393*053f45beSAndroid Build Coastguard Worker 		}
394*053f45beSAndroid Build Coastguard Worker 	}
395*053f45beSAndroid Build Coastguard Worker 
396*053f45beSAndroid Build Coastguard Worker 	return 0;
397*053f45beSAndroid Build Coastguard Worker }
398*053f45beSAndroid Build Coastguard Worker 
write_pid_to_tasks(char * tasks,pid_t pid)399*053f45beSAndroid Build Coastguard Worker static int write_pid_to_tasks(char *tasks, pid_t pid)
400*053f45beSAndroid Build Coastguard Worker {
401*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
402*053f45beSAndroid Build Coastguard Worker 
403*053f45beSAndroid Build Coastguard Worker 	fp = fopen(tasks, "w");
404*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
405*053f45beSAndroid Build Coastguard Worker 		perror("Failed to open tasks file");
406*053f45beSAndroid Build Coastguard Worker 
407*053f45beSAndroid Build Coastguard Worker 		return -1;
408*053f45beSAndroid Build Coastguard Worker 	}
409*053f45beSAndroid Build Coastguard Worker 	if (fprintf(fp, "%d\n", pid) < 0) {
410*053f45beSAndroid Build Coastguard Worker 		perror("Failed to wr pid to tasks file");
411*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
412*053f45beSAndroid Build Coastguard Worker 
413*053f45beSAndroid Build Coastguard Worker 		return -1;
414*053f45beSAndroid Build Coastguard Worker 	}
415*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
416*053f45beSAndroid Build Coastguard Worker 
417*053f45beSAndroid Build Coastguard Worker 	return 0;
418*053f45beSAndroid Build Coastguard Worker }
419*053f45beSAndroid Build Coastguard Worker 
420*053f45beSAndroid Build Coastguard Worker /*
421*053f45beSAndroid Build Coastguard Worker  * write_bm_pid_to_resctrl - Write a PID (i.e. benchmark) to resctrl FS
422*053f45beSAndroid Build Coastguard Worker  * @bm_pid:		PID that should be written
423*053f45beSAndroid Build Coastguard Worker  * @ctrlgrp:		Name of the control monitor group (con_mon grp)
424*053f45beSAndroid Build Coastguard Worker  * @mongrp:		Name of the monitor group (mon grp)
425*053f45beSAndroid Build Coastguard Worker  * @resctrl_val:	Resctrl feature (Eg: mbm, mba.. etc)
426*053f45beSAndroid Build Coastguard Worker  *
427*053f45beSAndroid Build Coastguard Worker  * If a con_mon grp is requested, create it and write pid to it, otherwise
428*053f45beSAndroid Build Coastguard Worker  * write pid to root con_mon grp.
429*053f45beSAndroid Build Coastguard Worker  * If a mon grp is requested, create it and write pid to it, otherwise
430*053f45beSAndroid Build Coastguard Worker  * pid is not written, this means that pid is in con_mon grp and hence
431*053f45beSAndroid Build Coastguard Worker  * should consult con_mon grp's mon_data directory for results.
432*053f45beSAndroid Build Coastguard Worker  *
433*053f45beSAndroid Build Coastguard Worker  * Return: 0 on success, non-zero on failure
434*053f45beSAndroid Build Coastguard Worker  */
write_bm_pid_to_resctrl(pid_t bm_pid,char * ctrlgrp,char * mongrp,char * resctrl_val)435*053f45beSAndroid Build Coastguard Worker int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
436*053f45beSAndroid Build Coastguard Worker 			    char *resctrl_val)
437*053f45beSAndroid Build Coastguard Worker {
438*053f45beSAndroid Build Coastguard Worker 	char controlgroup[128], monitorgroup[512], monitorgroup_p[256];
439*053f45beSAndroid Build Coastguard Worker 	char tasks[1024];
440*053f45beSAndroid Build Coastguard Worker 	int ret = 0;
441*053f45beSAndroid Build Coastguard Worker 
442*053f45beSAndroid Build Coastguard Worker 	if (strlen(ctrlgrp))
443*053f45beSAndroid Build Coastguard Worker 		sprintf(controlgroup, "%s/%s", RESCTRL_PATH, ctrlgrp);
444*053f45beSAndroid Build Coastguard Worker 	else
445*053f45beSAndroid Build Coastguard Worker 		sprintf(controlgroup, "%s", RESCTRL_PATH);
446*053f45beSAndroid Build Coastguard Worker 
447*053f45beSAndroid Build Coastguard Worker 	/* Create control and monitoring group and write pid into it */
448*053f45beSAndroid Build Coastguard Worker 	ret = create_grp(ctrlgrp, controlgroup, RESCTRL_PATH);
449*053f45beSAndroid Build Coastguard Worker 	if (ret)
450*053f45beSAndroid Build Coastguard Worker 		goto out;
451*053f45beSAndroid Build Coastguard Worker 	sprintf(tasks, "%s/tasks", controlgroup);
452*053f45beSAndroid Build Coastguard Worker 	ret = write_pid_to_tasks(tasks, bm_pid);
453*053f45beSAndroid Build Coastguard Worker 	if (ret)
454*053f45beSAndroid Build Coastguard Worker 		goto out;
455*053f45beSAndroid Build Coastguard Worker 
456*053f45beSAndroid Build Coastguard Worker 	/* Create mon grp and write pid into it for "mbm" and "cmt" test */
457*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)) ||
458*053f45beSAndroid Build Coastguard Worker 	    !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
459*053f45beSAndroid Build Coastguard Worker 		if (strlen(mongrp)) {
460*053f45beSAndroid Build Coastguard Worker 			sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
461*053f45beSAndroid Build Coastguard Worker 			sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
462*053f45beSAndroid Build Coastguard Worker 			ret = create_grp(mongrp, monitorgroup, monitorgroup_p);
463*053f45beSAndroid Build Coastguard Worker 			if (ret)
464*053f45beSAndroid Build Coastguard Worker 				goto out;
465*053f45beSAndroid Build Coastguard Worker 
466*053f45beSAndroid Build Coastguard Worker 			sprintf(tasks, "%s/mon_groups/%s/tasks",
467*053f45beSAndroid Build Coastguard Worker 				controlgroup, mongrp);
468*053f45beSAndroid Build Coastguard Worker 			ret = write_pid_to_tasks(tasks, bm_pid);
469*053f45beSAndroid Build Coastguard Worker 			if (ret)
470*053f45beSAndroid Build Coastguard Worker 				goto out;
471*053f45beSAndroid Build Coastguard Worker 		}
472*053f45beSAndroid Build Coastguard Worker 	}
473*053f45beSAndroid Build Coastguard Worker 
474*053f45beSAndroid Build Coastguard Worker out:
475*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Writing benchmark parameters to resctrl FS\n");
476*053f45beSAndroid Build Coastguard Worker 	if (ret)
477*053f45beSAndroid Build Coastguard Worker 		perror("# writing to resctrlfs");
478*053f45beSAndroid Build Coastguard Worker 
479*053f45beSAndroid Build Coastguard Worker 	return ret;
480*053f45beSAndroid Build Coastguard Worker }
481*053f45beSAndroid Build Coastguard Worker 
482*053f45beSAndroid Build Coastguard Worker /*
483*053f45beSAndroid Build Coastguard Worker  * write_schemata - Update schemata of a con_mon grp
484*053f45beSAndroid Build Coastguard Worker  * @ctrlgrp:		Name of the con_mon grp
485*053f45beSAndroid Build Coastguard Worker  * @schemata:		Schemata that should be updated to
486*053f45beSAndroid Build Coastguard Worker  * @cpu_no:		CPU number that the benchmark PID is binded to
487*053f45beSAndroid Build Coastguard Worker  * @resctrl_val:	Resctrl feature (Eg: mbm, mba.. etc)
488*053f45beSAndroid Build Coastguard Worker  *
489*053f45beSAndroid Build Coastguard Worker  * Update schemata of a con_mon grp *only* if requested resctrl feature is
490*053f45beSAndroid Build Coastguard Worker  * allocation type
491*053f45beSAndroid Build Coastguard Worker  *
492*053f45beSAndroid Build Coastguard Worker  * Return: 0 on success, non-zero on failure
493*053f45beSAndroid Build Coastguard Worker  */
write_schemata(char * ctrlgrp,char * schemata,int cpu_no,char * resctrl_val)494*053f45beSAndroid Build Coastguard Worker int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
495*053f45beSAndroid Build Coastguard Worker {
496*053f45beSAndroid Build Coastguard Worker 	char controlgroup[1024], schema[1024], reason[64];
497*053f45beSAndroid Build Coastguard Worker 	int resource_id, ret = 0;
498*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
499*053f45beSAndroid Build Coastguard Worker 
500*053f45beSAndroid Build Coastguard Worker 	if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
501*053f45beSAndroid Build Coastguard Worker 	    strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
502*053f45beSAndroid Build Coastguard Worker 	    strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
503*053f45beSAndroid Build Coastguard Worker 		return -ENOENT;
504*053f45beSAndroid Build Coastguard Worker 
505*053f45beSAndroid Build Coastguard Worker 	if (!schemata) {
506*053f45beSAndroid Build Coastguard Worker 		ksft_print_msg("Skipping empty schemata update\n");
507*053f45beSAndroid Build Coastguard Worker 
508*053f45beSAndroid Build Coastguard Worker 		return -1;
509*053f45beSAndroid Build Coastguard Worker 	}
510*053f45beSAndroid Build Coastguard Worker 
511*053f45beSAndroid Build Coastguard Worker 	if (get_resource_id(cpu_no, &resource_id) < 0) {
512*053f45beSAndroid Build Coastguard Worker 		sprintf(reason, "Failed to get resource id");
513*053f45beSAndroid Build Coastguard Worker 		ret = -1;
514*053f45beSAndroid Build Coastguard Worker 
515*053f45beSAndroid Build Coastguard Worker 		goto out;
516*053f45beSAndroid Build Coastguard Worker 	}
517*053f45beSAndroid Build Coastguard Worker 
518*053f45beSAndroid Build Coastguard Worker 	if (strlen(ctrlgrp) != 0)
519*053f45beSAndroid Build Coastguard Worker 		sprintf(controlgroup, "%s/%s/schemata", RESCTRL_PATH, ctrlgrp);
520*053f45beSAndroid Build Coastguard Worker 	else
521*053f45beSAndroid Build Coastguard Worker 		sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
522*053f45beSAndroid Build Coastguard Worker 
523*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
524*053f45beSAndroid Build Coastguard Worker 	    !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
525*053f45beSAndroid Build Coastguard Worker 		sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
526*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)))
527*053f45beSAndroid Build Coastguard Worker 		sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
528*053f45beSAndroid Build Coastguard Worker 
529*053f45beSAndroid Build Coastguard Worker 	fp = fopen(controlgroup, "w");
530*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
531*053f45beSAndroid Build Coastguard Worker 		sprintf(reason, "Failed to open control group");
532*053f45beSAndroid Build Coastguard Worker 		ret = -1;
533*053f45beSAndroid Build Coastguard Worker 
534*053f45beSAndroid Build Coastguard Worker 		goto out;
535*053f45beSAndroid Build Coastguard Worker 	}
536*053f45beSAndroid Build Coastguard Worker 
537*053f45beSAndroid Build Coastguard Worker 	if (fprintf(fp, "%s\n", schema) < 0) {
538*053f45beSAndroid Build Coastguard Worker 		sprintf(reason, "Failed to write schemata in control group");
539*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
540*053f45beSAndroid Build Coastguard Worker 		ret = -1;
541*053f45beSAndroid Build Coastguard Worker 
542*053f45beSAndroid Build Coastguard Worker 		goto out;
543*053f45beSAndroid Build Coastguard Worker 	}
544*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
545*053f45beSAndroid Build Coastguard Worker 
546*053f45beSAndroid Build Coastguard Worker out:
547*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Write schema \"%s\" to resctrl FS%s%s\n",
548*053f45beSAndroid Build Coastguard Worker 		       schema, ret ? " # " : "",
549*053f45beSAndroid Build Coastguard Worker 		       ret ? reason : "");
550*053f45beSAndroid Build Coastguard Worker 
551*053f45beSAndroid Build Coastguard Worker 	return ret;
552*053f45beSAndroid Build Coastguard Worker }
553*053f45beSAndroid Build Coastguard Worker 
check_resctrlfs_support(void)554*053f45beSAndroid Build Coastguard Worker bool check_resctrlfs_support(void)
555*053f45beSAndroid Build Coastguard Worker {
556*053f45beSAndroid Build Coastguard Worker 	FILE *inf = fopen("/proc/filesystems", "r");
557*053f45beSAndroid Build Coastguard Worker 	DIR *dp;
558*053f45beSAndroid Build Coastguard Worker 	char *res;
559*053f45beSAndroid Build Coastguard Worker 	bool ret = false;
560*053f45beSAndroid Build Coastguard Worker 
561*053f45beSAndroid Build Coastguard Worker 	if (!inf)
562*053f45beSAndroid Build Coastguard Worker 		return false;
563*053f45beSAndroid Build Coastguard Worker 
564*053f45beSAndroid Build Coastguard Worker 	res = fgrep(inf, "nodev\tresctrl\n");
565*053f45beSAndroid Build Coastguard Worker 
566*053f45beSAndroid Build Coastguard Worker 	if (res) {
567*053f45beSAndroid Build Coastguard Worker 		ret = true;
568*053f45beSAndroid Build Coastguard Worker 		free(res);
569*053f45beSAndroid Build Coastguard Worker 	}
570*053f45beSAndroid Build Coastguard Worker 
571*053f45beSAndroid Build Coastguard Worker 	fclose(inf);
572*053f45beSAndroid Build Coastguard Worker 
573*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("%s Check kernel supports resctrl filesystem\n",
574*053f45beSAndroid Build Coastguard Worker 		       ret ? "Pass:" : "Fail:");
575*053f45beSAndroid Build Coastguard Worker 
576*053f45beSAndroid Build Coastguard Worker 	if (!ret)
577*053f45beSAndroid Build Coastguard Worker 		return ret;
578*053f45beSAndroid Build Coastguard Worker 
579*053f45beSAndroid Build Coastguard Worker 	dp = opendir(RESCTRL_PATH);
580*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("%s Check resctrl mountpoint \"%s\" exists\n",
581*053f45beSAndroid Build Coastguard Worker 		       dp ? "Pass:" : "Fail:", RESCTRL_PATH);
582*053f45beSAndroid Build Coastguard Worker 	if (dp)
583*053f45beSAndroid Build Coastguard Worker 		closedir(dp);
584*053f45beSAndroid Build Coastguard Worker 
585*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("resctrl filesystem %s mounted\n",
586*053f45beSAndroid Build Coastguard Worker 		       find_resctrl_mount(NULL) ? "not" : "is");
587*053f45beSAndroid Build Coastguard Worker 
588*053f45beSAndroid Build Coastguard Worker 	return ret;
589*053f45beSAndroid Build Coastguard Worker }
590*053f45beSAndroid Build Coastguard Worker 
fgrep(FILE * inf,const char * str)591*053f45beSAndroid Build Coastguard Worker char *fgrep(FILE *inf, const char *str)
592*053f45beSAndroid Build Coastguard Worker {
593*053f45beSAndroid Build Coastguard Worker 	char line[256];
594*053f45beSAndroid Build Coastguard Worker 	int slen = strlen(str);
595*053f45beSAndroid Build Coastguard Worker 
596*053f45beSAndroid Build Coastguard Worker 	while (!feof(inf)) {
597*053f45beSAndroid Build Coastguard Worker 		if (!fgets(line, 256, inf))
598*053f45beSAndroid Build Coastguard Worker 			break;
599*053f45beSAndroid Build Coastguard Worker 		if (strncmp(line, str, slen))
600*053f45beSAndroid Build Coastguard Worker 			continue;
601*053f45beSAndroid Build Coastguard Worker 
602*053f45beSAndroid Build Coastguard Worker 		return strdup(line);
603*053f45beSAndroid Build Coastguard Worker 	}
604*053f45beSAndroid Build Coastguard Worker 
605*053f45beSAndroid Build Coastguard Worker 	return NULL;
606*053f45beSAndroid Build Coastguard Worker }
607*053f45beSAndroid Build Coastguard Worker 
608*053f45beSAndroid Build Coastguard Worker /*
609*053f45beSAndroid Build Coastguard Worker  * validate_resctrl_feature_request - Check if requested feature is valid.
610*053f45beSAndroid Build Coastguard Worker  * @resctrl_val:	Requested feature
611*053f45beSAndroid Build Coastguard Worker  *
612*053f45beSAndroid Build Coastguard Worker  * Return: True if the feature is supported, else false
613*053f45beSAndroid Build Coastguard Worker  */
validate_resctrl_feature_request(const char * resctrl_val)614*053f45beSAndroid Build Coastguard Worker bool validate_resctrl_feature_request(const char *resctrl_val)
615*053f45beSAndroid Build Coastguard Worker {
616*053f45beSAndroid Build Coastguard Worker 	struct stat statbuf;
617*053f45beSAndroid Build Coastguard Worker 	bool found = false;
618*053f45beSAndroid Build Coastguard Worker 	char *res;
619*053f45beSAndroid Build Coastguard Worker 	FILE *inf;
620*053f45beSAndroid Build Coastguard Worker 
621*053f45beSAndroid Build Coastguard Worker 	if (!resctrl_val)
622*053f45beSAndroid Build Coastguard Worker 		return false;
623*053f45beSAndroid Build Coastguard Worker 
624*053f45beSAndroid Build Coastguard Worker 	if (remount_resctrlfs(false))
625*053f45beSAndroid Build Coastguard Worker 		return false;
626*053f45beSAndroid Build Coastguard Worker 
627*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
628*053f45beSAndroid Build Coastguard Worker 		if (!stat(L3_PATH, &statbuf))
629*053f45beSAndroid Build Coastguard Worker 			return true;
630*053f45beSAndroid Build Coastguard Worker 	} else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
631*053f45beSAndroid Build Coastguard Worker 		if (!stat(MB_PATH, &statbuf))
632*053f45beSAndroid Build Coastguard Worker 			return true;
633*053f45beSAndroid Build Coastguard Worker 	} else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
634*053f45beSAndroid Build Coastguard Worker 		   !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
635*053f45beSAndroid Build Coastguard Worker 		if (!stat(L3_MON_PATH, &statbuf)) {
636*053f45beSAndroid Build Coastguard Worker 			inf = fopen(L3_MON_FEATURES_PATH, "r");
637*053f45beSAndroid Build Coastguard Worker 			if (!inf)
638*053f45beSAndroid Build Coastguard Worker 				return false;
639*053f45beSAndroid Build Coastguard Worker 
640*053f45beSAndroid Build Coastguard Worker 			if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
641*053f45beSAndroid Build Coastguard Worker 				res = fgrep(inf, "llc_occupancy");
642*053f45beSAndroid Build Coastguard Worker 				if (res) {
643*053f45beSAndroid Build Coastguard Worker 					found = true;
644*053f45beSAndroid Build Coastguard Worker 					free(res);
645*053f45beSAndroid Build Coastguard Worker 				}
646*053f45beSAndroid Build Coastguard Worker 			}
647*053f45beSAndroid Build Coastguard Worker 
648*053f45beSAndroid Build Coastguard Worker 			if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
649*053f45beSAndroid Build Coastguard Worker 				res = fgrep(inf, "mbm_total_bytes");
650*053f45beSAndroid Build Coastguard Worker 				if (res) {
651*053f45beSAndroid Build Coastguard Worker 					free(res);
652*053f45beSAndroid Build Coastguard Worker 					res = fgrep(inf, "mbm_local_bytes");
653*053f45beSAndroid Build Coastguard Worker 					if (res) {
654*053f45beSAndroid Build Coastguard Worker 						found = true;
655*053f45beSAndroid Build Coastguard Worker 						free(res);
656*053f45beSAndroid Build Coastguard Worker 					}
657*053f45beSAndroid Build Coastguard Worker 				}
658*053f45beSAndroid Build Coastguard Worker 			}
659*053f45beSAndroid Build Coastguard Worker 			fclose(inf);
660*053f45beSAndroid Build Coastguard Worker 		}
661*053f45beSAndroid Build Coastguard Worker 	}
662*053f45beSAndroid Build Coastguard Worker 
663*053f45beSAndroid Build Coastguard Worker 	return found;
664*053f45beSAndroid Build Coastguard Worker }
665*053f45beSAndroid Build Coastguard Worker 
filter_dmesg(void)666*053f45beSAndroid Build Coastguard Worker int filter_dmesg(void)
667*053f45beSAndroid Build Coastguard Worker {
668*053f45beSAndroid Build Coastguard Worker 	char line[1024];
669*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
670*053f45beSAndroid Build Coastguard Worker 	int pipefds[2];
671*053f45beSAndroid Build Coastguard Worker 	pid_t pid;
672*053f45beSAndroid Build Coastguard Worker 	int ret;
673*053f45beSAndroid Build Coastguard Worker 
674*053f45beSAndroid Build Coastguard Worker 	ret = pipe(pipefds);
675*053f45beSAndroid Build Coastguard Worker 	if (ret) {
676*053f45beSAndroid Build Coastguard Worker 		perror("pipe");
677*053f45beSAndroid Build Coastguard Worker 		return ret;
678*053f45beSAndroid Build Coastguard Worker 	}
679*053f45beSAndroid Build Coastguard Worker 	pid = fork();
680*053f45beSAndroid Build Coastguard Worker 	if (pid == 0) {
681*053f45beSAndroid Build Coastguard Worker 		close(pipefds[0]);
682*053f45beSAndroid Build Coastguard Worker 		dup2(pipefds[1], STDOUT_FILENO);
683*053f45beSAndroid Build Coastguard Worker 		execlp("dmesg", "dmesg", NULL);
684*053f45beSAndroid Build Coastguard Worker 		perror("executing dmesg");
685*053f45beSAndroid Build Coastguard Worker 		exit(1);
686*053f45beSAndroid Build Coastguard Worker 	}
687*053f45beSAndroid Build Coastguard Worker 	close(pipefds[1]);
688*053f45beSAndroid Build Coastguard Worker 	fp = fdopen(pipefds[0], "r");
689*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
690*053f45beSAndroid Build Coastguard Worker 		perror("fdopen(pipe)");
691*053f45beSAndroid Build Coastguard Worker 		kill(pid, SIGTERM);
692*053f45beSAndroid Build Coastguard Worker 
693*053f45beSAndroid Build Coastguard Worker 		return -1;
694*053f45beSAndroid Build Coastguard Worker 	}
695*053f45beSAndroid Build Coastguard Worker 
696*053f45beSAndroid Build Coastguard Worker 	while (fgets(line, 1024, fp)) {
697*053f45beSAndroid Build Coastguard Worker 		if (strstr(line, "intel_rdt:"))
698*053f45beSAndroid Build Coastguard Worker 			ksft_print_msg("dmesg: %s", line);
699*053f45beSAndroid Build Coastguard Worker 		if (strstr(line, "resctrl:"))
700*053f45beSAndroid Build Coastguard Worker 			ksft_print_msg("dmesg: %s", line);
701*053f45beSAndroid Build Coastguard Worker 	}
702*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
703*053f45beSAndroid Build Coastguard Worker 	waitpid(pid, NULL, 0);
704*053f45beSAndroid Build Coastguard Worker 
705*053f45beSAndroid Build Coastguard Worker 	return 0;
706*053f45beSAndroid Build Coastguard Worker }
707*053f45beSAndroid Build Coastguard Worker 
validate_bw_report_request(char * bw_report)708*053f45beSAndroid Build Coastguard Worker int validate_bw_report_request(char *bw_report)
709*053f45beSAndroid Build Coastguard Worker {
710*053f45beSAndroid Build Coastguard Worker 	if (strcmp(bw_report, "reads") == 0)
711*053f45beSAndroid Build Coastguard Worker 		return 0;
712*053f45beSAndroid Build Coastguard Worker 	if (strcmp(bw_report, "writes") == 0)
713*053f45beSAndroid Build Coastguard Worker 		return 0;
714*053f45beSAndroid Build Coastguard Worker 	if (strcmp(bw_report, "nt-writes") == 0) {
715*053f45beSAndroid Build Coastguard Worker 		strcpy(bw_report, "writes");
716*053f45beSAndroid Build Coastguard Worker 		return 0;
717*053f45beSAndroid Build Coastguard Worker 	}
718*053f45beSAndroid Build Coastguard Worker 	if (strcmp(bw_report, "total") == 0)
719*053f45beSAndroid Build Coastguard Worker 		return 0;
720*053f45beSAndroid Build Coastguard Worker 
721*053f45beSAndroid Build Coastguard Worker 	fprintf(stderr, "Requested iMC B/W report type unavailable\n");
722*053f45beSAndroid Build Coastguard Worker 
723*053f45beSAndroid Build Coastguard Worker 	return -1;
724*053f45beSAndroid Build Coastguard Worker }
725*053f45beSAndroid Build Coastguard Worker 
perf_event_open(struct perf_event_attr * hw_event,pid_t pid,int cpu,int group_fd,unsigned long flags)726*053f45beSAndroid Build Coastguard Worker int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
727*053f45beSAndroid Build Coastguard Worker 		    int group_fd, unsigned long flags)
728*053f45beSAndroid Build Coastguard Worker {
729*053f45beSAndroid Build Coastguard Worker 	int ret;
730*053f45beSAndroid Build Coastguard Worker 
731*053f45beSAndroid Build Coastguard Worker 	ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
732*053f45beSAndroid Build Coastguard Worker 		      group_fd, flags);
733*053f45beSAndroid Build Coastguard Worker 	return ret;
734*053f45beSAndroid Build Coastguard Worker }
735*053f45beSAndroid Build Coastguard Worker 
count_bits(unsigned long n)736*053f45beSAndroid Build Coastguard Worker unsigned int count_bits(unsigned long n)
737*053f45beSAndroid Build Coastguard Worker {
738*053f45beSAndroid Build Coastguard Worker 	unsigned int count = 0;
739*053f45beSAndroid Build Coastguard Worker 
740*053f45beSAndroid Build Coastguard Worker 	while (n) {
741*053f45beSAndroid Build Coastguard Worker 		count += n & 1;
742*053f45beSAndroid Build Coastguard Worker 		n >>= 1;
743*053f45beSAndroid Build Coastguard Worker 	}
744*053f45beSAndroid Build Coastguard Worker 
745*053f45beSAndroid Build Coastguard Worker 	return count;
746*053f45beSAndroid Build Coastguard Worker }
747