xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/resctrl/cache.c (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
1*053f45beSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*053f45beSAndroid Build Coastguard Worker 
3*053f45beSAndroid Build Coastguard Worker #include <stdint.h>
4*053f45beSAndroid Build Coastguard Worker #include "resctrl.h"
5*053f45beSAndroid Build Coastguard Worker 
6*053f45beSAndroid Build Coastguard Worker struct read_format {
7*053f45beSAndroid Build Coastguard Worker 	__u64 nr;			/* The number of events */
8*053f45beSAndroid Build Coastguard Worker 	struct {
9*053f45beSAndroid Build Coastguard Worker 		__u64 value;		/* The value of the event */
10*053f45beSAndroid Build Coastguard Worker 	} values[2];
11*053f45beSAndroid Build Coastguard Worker };
12*053f45beSAndroid Build Coastguard Worker 
13*053f45beSAndroid Build Coastguard Worker static struct perf_event_attr pea_llc_miss;
14*053f45beSAndroid Build Coastguard Worker static struct read_format rf_cqm;
15*053f45beSAndroid Build Coastguard Worker static int fd_lm;
16*053f45beSAndroid Build Coastguard Worker char llc_occup_path[1024];
17*053f45beSAndroid Build Coastguard Worker 
initialize_perf_event_attr(void)18*053f45beSAndroid Build Coastguard Worker static void initialize_perf_event_attr(void)
19*053f45beSAndroid Build Coastguard Worker {
20*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.type = PERF_TYPE_HARDWARE;
21*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.size = sizeof(struct perf_event_attr);
22*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.read_format = PERF_FORMAT_GROUP;
23*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.exclude_kernel = 1;
24*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.exclude_hv = 1;
25*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.exclude_idle = 1;
26*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.exclude_callchain_kernel = 1;
27*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.inherit = 1;
28*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.exclude_guest = 1;
29*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.disabled = 1;
30*053f45beSAndroid Build Coastguard Worker }
31*053f45beSAndroid Build Coastguard Worker 
ioctl_perf_event_ioc_reset_enable(void)32*053f45beSAndroid Build Coastguard Worker static void ioctl_perf_event_ioc_reset_enable(void)
33*053f45beSAndroid Build Coastguard Worker {
34*053f45beSAndroid Build Coastguard Worker 	ioctl(fd_lm, PERF_EVENT_IOC_RESET, 0);
35*053f45beSAndroid Build Coastguard Worker 	ioctl(fd_lm, PERF_EVENT_IOC_ENABLE, 0);
36*053f45beSAndroid Build Coastguard Worker }
37*053f45beSAndroid Build Coastguard Worker 
perf_event_open_llc_miss(pid_t pid,int cpu_no)38*053f45beSAndroid Build Coastguard Worker static int perf_event_open_llc_miss(pid_t pid, int cpu_no)
39*053f45beSAndroid Build Coastguard Worker {
40*053f45beSAndroid Build Coastguard Worker 	fd_lm = perf_event_open(&pea_llc_miss, pid, cpu_no, -1,
41*053f45beSAndroid Build Coastguard Worker 				PERF_FLAG_FD_CLOEXEC);
42*053f45beSAndroid Build Coastguard Worker 	if (fd_lm == -1) {
43*053f45beSAndroid Build Coastguard Worker 		perror("Error opening leader");
44*053f45beSAndroid Build Coastguard Worker 		ctrlc_handler(0, NULL, NULL);
45*053f45beSAndroid Build Coastguard Worker 		return -1;
46*053f45beSAndroid Build Coastguard Worker 	}
47*053f45beSAndroid Build Coastguard Worker 
48*053f45beSAndroid Build Coastguard Worker 	return 0;
49*053f45beSAndroid Build Coastguard Worker }
50*053f45beSAndroid Build Coastguard Worker 
initialize_llc_perf(void)51*053f45beSAndroid Build Coastguard Worker static int initialize_llc_perf(void)
52*053f45beSAndroid Build Coastguard Worker {
53*053f45beSAndroid Build Coastguard Worker 	memset(&pea_llc_miss, 0, sizeof(struct perf_event_attr));
54*053f45beSAndroid Build Coastguard Worker 	memset(&rf_cqm, 0, sizeof(struct read_format));
55*053f45beSAndroid Build Coastguard Worker 
56*053f45beSAndroid Build Coastguard Worker 	/* Initialize perf_event_attr structures for HW_CACHE_MISSES */
57*053f45beSAndroid Build Coastguard Worker 	initialize_perf_event_attr();
58*053f45beSAndroid Build Coastguard Worker 
59*053f45beSAndroid Build Coastguard Worker 	pea_llc_miss.config = PERF_COUNT_HW_CACHE_MISSES;
60*053f45beSAndroid Build Coastguard Worker 
61*053f45beSAndroid Build Coastguard Worker 	rf_cqm.nr = 1;
62*053f45beSAndroid Build Coastguard Worker 
63*053f45beSAndroid Build Coastguard Worker 	return 0;
64*053f45beSAndroid Build Coastguard Worker }
65*053f45beSAndroid Build Coastguard Worker 
reset_enable_llc_perf(pid_t pid,int cpu_no)66*053f45beSAndroid Build Coastguard Worker static int reset_enable_llc_perf(pid_t pid, int cpu_no)
67*053f45beSAndroid Build Coastguard Worker {
68*053f45beSAndroid Build Coastguard Worker 	int ret = 0;
69*053f45beSAndroid Build Coastguard Worker 
70*053f45beSAndroid Build Coastguard Worker 	ret = perf_event_open_llc_miss(pid, cpu_no);
71*053f45beSAndroid Build Coastguard Worker 	if (ret < 0)
72*053f45beSAndroid Build Coastguard Worker 		return ret;
73*053f45beSAndroid Build Coastguard Worker 
74*053f45beSAndroid Build Coastguard Worker 	/* Start counters to log values */
75*053f45beSAndroid Build Coastguard Worker 	ioctl_perf_event_ioc_reset_enable();
76*053f45beSAndroid Build Coastguard Worker 
77*053f45beSAndroid Build Coastguard Worker 	return 0;
78*053f45beSAndroid Build Coastguard Worker }
79*053f45beSAndroid Build Coastguard Worker 
80*053f45beSAndroid Build Coastguard Worker /*
81*053f45beSAndroid Build Coastguard Worker  * get_llc_perf:	llc cache miss through perf events
82*053f45beSAndroid Build Coastguard Worker  * @cpu_no:		CPU number that the benchmark PID is binded to
83*053f45beSAndroid Build Coastguard Worker  *
84*053f45beSAndroid Build Coastguard Worker  * Perf events like HW_CACHE_MISSES could be used to validate number of
85*053f45beSAndroid Build Coastguard Worker  * cache lines allocated.
86*053f45beSAndroid Build Coastguard Worker  *
87*053f45beSAndroid Build Coastguard Worker  * Return: =0 on success.  <0 on failure.
88*053f45beSAndroid Build Coastguard Worker  */
get_llc_perf(unsigned long * llc_perf_miss)89*053f45beSAndroid Build Coastguard Worker static int get_llc_perf(unsigned long *llc_perf_miss)
90*053f45beSAndroid Build Coastguard Worker {
91*053f45beSAndroid Build Coastguard Worker 	__u64 total_misses;
92*053f45beSAndroid Build Coastguard Worker 
93*053f45beSAndroid Build Coastguard Worker 	/* Stop counters after one span to get miss rate */
94*053f45beSAndroid Build Coastguard Worker 
95*053f45beSAndroid Build Coastguard Worker 	ioctl(fd_lm, PERF_EVENT_IOC_DISABLE, 0);
96*053f45beSAndroid Build Coastguard Worker 
97*053f45beSAndroid Build Coastguard Worker 	if (read(fd_lm, &rf_cqm, sizeof(struct read_format)) == -1) {
98*053f45beSAndroid Build Coastguard Worker 		perror("Could not get llc misses through perf");
99*053f45beSAndroid Build Coastguard Worker 
100*053f45beSAndroid Build Coastguard Worker 		return -1;
101*053f45beSAndroid Build Coastguard Worker 	}
102*053f45beSAndroid Build Coastguard Worker 
103*053f45beSAndroid Build Coastguard Worker 	total_misses = rf_cqm.values[0].value;
104*053f45beSAndroid Build Coastguard Worker 
105*053f45beSAndroid Build Coastguard Worker 	close(fd_lm);
106*053f45beSAndroid Build Coastguard Worker 
107*053f45beSAndroid Build Coastguard Worker 	*llc_perf_miss = total_misses;
108*053f45beSAndroid Build Coastguard Worker 
109*053f45beSAndroid Build Coastguard Worker 	return 0;
110*053f45beSAndroid Build Coastguard Worker }
111*053f45beSAndroid Build Coastguard Worker 
112*053f45beSAndroid Build Coastguard Worker /*
113*053f45beSAndroid Build Coastguard Worker  * Get LLC Occupancy as reported by RESCTRL FS
114*053f45beSAndroid Build Coastguard Worker  * For CMT,
115*053f45beSAndroid Build Coastguard Worker  * 1. If con_mon grp and mon grp given, then read from mon grp in
116*053f45beSAndroid Build Coastguard Worker  * con_mon grp
117*053f45beSAndroid Build Coastguard Worker  * 2. If only con_mon grp given, then read from con_mon grp
118*053f45beSAndroid Build Coastguard Worker  * 3. If both not given, then read from root con_mon grp
119*053f45beSAndroid Build Coastguard Worker  * For CAT,
120*053f45beSAndroid Build Coastguard Worker  * 1. If con_mon grp given, then read from it
121*053f45beSAndroid Build Coastguard Worker  * 2. If con_mon grp not given, then read from root con_mon grp
122*053f45beSAndroid Build Coastguard Worker  *
123*053f45beSAndroid Build Coastguard Worker  * Return: =0 on success.  <0 on failure.
124*053f45beSAndroid Build Coastguard Worker  */
get_llc_occu_resctrl(unsigned long * llc_occupancy)125*053f45beSAndroid Build Coastguard Worker static int get_llc_occu_resctrl(unsigned long *llc_occupancy)
126*053f45beSAndroid Build Coastguard Worker {
127*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
128*053f45beSAndroid Build Coastguard Worker 
129*053f45beSAndroid Build Coastguard Worker 	fp = fopen(llc_occup_path, "r");
130*053f45beSAndroid Build Coastguard Worker 	if (!fp) {
131*053f45beSAndroid Build Coastguard Worker 		perror("Failed to open results file");
132*053f45beSAndroid Build Coastguard Worker 
133*053f45beSAndroid Build Coastguard Worker 		return errno;
134*053f45beSAndroid Build Coastguard Worker 	}
135*053f45beSAndroid Build Coastguard Worker 	if (fscanf(fp, "%lu", llc_occupancy) <= 0) {
136*053f45beSAndroid Build Coastguard Worker 		perror("Could not get llc occupancy");
137*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
138*053f45beSAndroid Build Coastguard Worker 
139*053f45beSAndroid Build Coastguard Worker 		return -1;
140*053f45beSAndroid Build Coastguard Worker 	}
141*053f45beSAndroid Build Coastguard Worker 	fclose(fp);
142*053f45beSAndroid Build Coastguard Worker 
143*053f45beSAndroid Build Coastguard Worker 	return 0;
144*053f45beSAndroid Build Coastguard Worker }
145*053f45beSAndroid Build Coastguard Worker 
146*053f45beSAndroid Build Coastguard Worker /*
147*053f45beSAndroid Build Coastguard Worker  * print_results_cache:	the cache results are stored in a file
148*053f45beSAndroid Build Coastguard Worker  * @filename:		file that stores the results
149*053f45beSAndroid Build Coastguard Worker  * @bm_pid:		child pid that runs benchmark
150*053f45beSAndroid Build Coastguard Worker  * @llc_value:		perf miss value /
151*053f45beSAndroid Build Coastguard Worker  *			llc occupancy value reported by resctrl FS
152*053f45beSAndroid Build Coastguard Worker  *
153*053f45beSAndroid Build Coastguard Worker  * Return:		0 on success. non-zero on failure.
154*053f45beSAndroid Build Coastguard Worker  */
print_results_cache(char * filename,int bm_pid,unsigned long llc_value)155*053f45beSAndroid Build Coastguard Worker static int print_results_cache(char *filename, int bm_pid,
156*053f45beSAndroid Build Coastguard Worker 			       unsigned long llc_value)
157*053f45beSAndroid Build Coastguard Worker {
158*053f45beSAndroid Build Coastguard Worker 	FILE *fp;
159*053f45beSAndroid Build Coastguard Worker 
160*053f45beSAndroid Build Coastguard Worker 	if (strcmp(filename, "stdio") == 0 || strcmp(filename, "stderr") == 0) {
161*053f45beSAndroid Build Coastguard Worker 		printf("Pid: %d \t LLC_value: %lu\n", bm_pid,
162*053f45beSAndroid Build Coastguard Worker 		       llc_value);
163*053f45beSAndroid Build Coastguard Worker 	} else {
164*053f45beSAndroid Build Coastguard Worker 		fp = fopen(filename, "a");
165*053f45beSAndroid Build Coastguard Worker 		if (!fp) {
166*053f45beSAndroid Build Coastguard Worker 			perror("Cannot open results file");
167*053f45beSAndroid Build Coastguard Worker 
168*053f45beSAndroid Build Coastguard Worker 			return errno;
169*053f45beSAndroid Build Coastguard Worker 		}
170*053f45beSAndroid Build Coastguard Worker 		fprintf(fp, "Pid: %d \t llc_value: %lu\n", bm_pid, llc_value);
171*053f45beSAndroid Build Coastguard Worker 		fclose(fp);
172*053f45beSAndroid Build Coastguard Worker 	}
173*053f45beSAndroid Build Coastguard Worker 
174*053f45beSAndroid Build Coastguard Worker 	return 0;
175*053f45beSAndroid Build Coastguard Worker }
176*053f45beSAndroid Build Coastguard Worker 
measure_cache_vals(struct resctrl_val_param * param,int bm_pid)177*053f45beSAndroid Build Coastguard Worker int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
178*053f45beSAndroid Build Coastguard Worker {
179*053f45beSAndroid Build Coastguard Worker 	unsigned long llc_perf_miss = 0, llc_occu_resc = 0, llc_value = 0;
180*053f45beSAndroid Build Coastguard Worker 	int ret;
181*053f45beSAndroid Build Coastguard Worker 
182*053f45beSAndroid Build Coastguard Worker 	/*
183*053f45beSAndroid Build Coastguard Worker 	 * Measure cache miss from perf.
184*053f45beSAndroid Build Coastguard Worker 	 */
185*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(param->resctrl_val, CAT_STR, sizeof(CAT_STR))) {
186*053f45beSAndroid Build Coastguard Worker 		ret = get_llc_perf(&llc_perf_miss);
187*053f45beSAndroid Build Coastguard Worker 		if (ret < 0)
188*053f45beSAndroid Build Coastguard Worker 			return ret;
189*053f45beSAndroid Build Coastguard Worker 		llc_value = llc_perf_miss;
190*053f45beSAndroid Build Coastguard Worker 	}
191*053f45beSAndroid Build Coastguard Worker 
192*053f45beSAndroid Build Coastguard Worker 	/*
193*053f45beSAndroid Build Coastguard Worker 	 * Measure llc occupancy from resctrl.
194*053f45beSAndroid Build Coastguard Worker 	 */
195*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(param->resctrl_val, CMT_STR, sizeof(CMT_STR))) {
196*053f45beSAndroid Build Coastguard Worker 		ret = get_llc_occu_resctrl(&llc_occu_resc);
197*053f45beSAndroid Build Coastguard Worker 		if (ret < 0)
198*053f45beSAndroid Build Coastguard Worker 			return ret;
199*053f45beSAndroid Build Coastguard Worker 		llc_value = llc_occu_resc;
200*053f45beSAndroid Build Coastguard Worker 	}
201*053f45beSAndroid Build Coastguard Worker 	ret = print_results_cache(param->filename, bm_pid, llc_value);
202*053f45beSAndroid Build Coastguard Worker 	if (ret)
203*053f45beSAndroid Build Coastguard Worker 		return ret;
204*053f45beSAndroid Build Coastguard Worker 
205*053f45beSAndroid Build Coastguard Worker 	return 0;
206*053f45beSAndroid Build Coastguard Worker }
207*053f45beSAndroid Build Coastguard Worker 
208*053f45beSAndroid Build Coastguard Worker /*
209*053f45beSAndroid Build Coastguard Worker  * cache_val:		execute benchmark and measure LLC occupancy resctrl
210*053f45beSAndroid Build Coastguard Worker  * and perf cache miss for the benchmark
211*053f45beSAndroid Build Coastguard Worker  * @param:		parameters passed to cache_val()
212*053f45beSAndroid Build Coastguard Worker  *
213*053f45beSAndroid Build Coastguard Worker  * Return:		0 on success. non-zero on failure.
214*053f45beSAndroid Build Coastguard Worker  */
cat_val(struct resctrl_val_param * param)215*053f45beSAndroid Build Coastguard Worker int cat_val(struct resctrl_val_param *param)
216*053f45beSAndroid Build Coastguard Worker {
217*053f45beSAndroid Build Coastguard Worker 	int malloc_and_init_memory = 1, memflush = 1, operation = 0, ret = 0;
218*053f45beSAndroid Build Coastguard Worker 	char *resctrl_val = param->resctrl_val;
219*053f45beSAndroid Build Coastguard Worker 	pid_t bm_pid;
220*053f45beSAndroid Build Coastguard Worker 
221*053f45beSAndroid Build Coastguard Worker 	if (strcmp(param->filename, "") == 0)
222*053f45beSAndroid Build Coastguard Worker 		sprintf(param->filename, "stdio");
223*053f45beSAndroid Build Coastguard Worker 
224*053f45beSAndroid Build Coastguard Worker 	bm_pid = getpid();
225*053f45beSAndroid Build Coastguard Worker 
226*053f45beSAndroid Build Coastguard Worker 	/* Taskset benchmark to specified cpu */
227*053f45beSAndroid Build Coastguard Worker 	ret = taskset_benchmark(bm_pid, param->cpu_no);
228*053f45beSAndroid Build Coastguard Worker 	if (ret)
229*053f45beSAndroid Build Coastguard Worker 		return ret;
230*053f45beSAndroid Build Coastguard Worker 
231*053f45beSAndroid Build Coastguard Worker 	/* Write benchmark to specified con_mon grp, mon_grp in resctrl FS*/
232*053f45beSAndroid Build Coastguard Worker 	ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
233*053f45beSAndroid Build Coastguard Worker 				      resctrl_val);
234*053f45beSAndroid Build Coastguard Worker 	if (ret)
235*053f45beSAndroid Build Coastguard Worker 		return ret;
236*053f45beSAndroid Build Coastguard Worker 
237*053f45beSAndroid Build Coastguard Worker 	if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
238*053f45beSAndroid Build Coastguard Worker 		ret = initialize_llc_perf();
239*053f45beSAndroid Build Coastguard Worker 		if (ret)
240*053f45beSAndroid Build Coastguard Worker 			return ret;
241*053f45beSAndroid Build Coastguard Worker 	}
242*053f45beSAndroid Build Coastguard Worker 
243*053f45beSAndroid Build Coastguard Worker 	/* Test runs until the callback setup() tells the test to stop. */
244*053f45beSAndroid Build Coastguard Worker 	while (1) {
245*053f45beSAndroid Build Coastguard Worker 		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
246*053f45beSAndroid Build Coastguard Worker 			ret = param->setup(1, param);
247*053f45beSAndroid Build Coastguard Worker 			if (ret) {
248*053f45beSAndroid Build Coastguard Worker 				ret = 0;
249*053f45beSAndroid Build Coastguard Worker 				break;
250*053f45beSAndroid Build Coastguard Worker 			}
251*053f45beSAndroid Build Coastguard Worker 			ret = reset_enable_llc_perf(bm_pid, param->cpu_no);
252*053f45beSAndroid Build Coastguard Worker 			if (ret)
253*053f45beSAndroid Build Coastguard Worker 				break;
254*053f45beSAndroid Build Coastguard Worker 
255*053f45beSAndroid Build Coastguard Worker 			if (run_fill_buf(param->span, malloc_and_init_memory,
256*053f45beSAndroid Build Coastguard Worker 					 memflush, operation, resctrl_val)) {
257*053f45beSAndroid Build Coastguard Worker 				fprintf(stderr, "Error-running fill buffer\n");
258*053f45beSAndroid Build Coastguard Worker 				ret = -1;
259*053f45beSAndroid Build Coastguard Worker 				break;
260*053f45beSAndroid Build Coastguard Worker 			}
261*053f45beSAndroid Build Coastguard Worker 
262*053f45beSAndroid Build Coastguard Worker 			sleep(1);
263*053f45beSAndroid Build Coastguard Worker 			ret = measure_cache_vals(param, bm_pid);
264*053f45beSAndroid Build Coastguard Worker 			if (ret)
265*053f45beSAndroid Build Coastguard Worker 				break;
266*053f45beSAndroid Build Coastguard Worker 		} else {
267*053f45beSAndroid Build Coastguard Worker 			break;
268*053f45beSAndroid Build Coastguard Worker 		}
269*053f45beSAndroid Build Coastguard Worker 	}
270*053f45beSAndroid Build Coastguard Worker 
271*053f45beSAndroid Build Coastguard Worker 	return ret;
272*053f45beSAndroid Build Coastguard Worker }
273*053f45beSAndroid Build Coastguard Worker 
274*053f45beSAndroid Build Coastguard Worker /*
275*053f45beSAndroid Build Coastguard Worker  * show_cache_info:	show cache test result information
276*053f45beSAndroid Build Coastguard Worker  * @sum_llc_val:	sum of LLC cache result data
277*053f45beSAndroid Build Coastguard Worker  * @no_of_bits:		number of bits
278*053f45beSAndroid Build Coastguard Worker  * @cache_span:		cache span in bytes for CMT or in lines for CAT
279*053f45beSAndroid Build Coastguard Worker  * @max_diff:		max difference
280*053f45beSAndroid Build Coastguard Worker  * @max_diff_percent:	max difference percentage
281*053f45beSAndroid Build Coastguard Worker  * @num_of_runs:	number of runs
282*053f45beSAndroid Build Coastguard Worker  * @platform:		show test information on this platform
283*053f45beSAndroid Build Coastguard Worker  * @cmt:		CMT test or CAT test
284*053f45beSAndroid Build Coastguard Worker  *
285*053f45beSAndroid Build Coastguard Worker  * Return:		0 on success. non-zero on failure.
286*053f45beSAndroid Build Coastguard Worker  */
show_cache_info(unsigned long sum_llc_val,int no_of_bits,unsigned long cache_span,unsigned long max_diff,unsigned long max_diff_percent,unsigned long num_of_runs,bool platform,bool cmt)287*053f45beSAndroid Build Coastguard Worker int show_cache_info(unsigned long sum_llc_val, int no_of_bits,
288*053f45beSAndroid Build Coastguard Worker 		    unsigned long cache_span, unsigned long max_diff,
289*053f45beSAndroid Build Coastguard Worker 		    unsigned long max_diff_percent, unsigned long num_of_runs,
290*053f45beSAndroid Build Coastguard Worker 		    bool platform, bool cmt)
291*053f45beSAndroid Build Coastguard Worker {
292*053f45beSAndroid Build Coastguard Worker 	unsigned long avg_llc_val = 0;
293*053f45beSAndroid Build Coastguard Worker 	float diff_percent;
294*053f45beSAndroid Build Coastguard Worker 	long avg_diff = 0;
295*053f45beSAndroid Build Coastguard Worker 	int ret;
296*053f45beSAndroid Build Coastguard Worker 
297*053f45beSAndroid Build Coastguard Worker 	avg_llc_val = sum_llc_val / (num_of_runs - 1);
298*053f45beSAndroid Build Coastguard Worker 	avg_diff = (long)abs(cache_span - avg_llc_val);
299*053f45beSAndroid Build Coastguard Worker 	diff_percent = ((float)cache_span - avg_llc_val) / cache_span * 100;
300*053f45beSAndroid Build Coastguard Worker 
301*053f45beSAndroid Build Coastguard Worker 	ret = platform && abs((int)diff_percent) > max_diff_percent &&
302*053f45beSAndroid Build Coastguard Worker 	      (cmt ? (abs(avg_diff) > max_diff) : true);
303*053f45beSAndroid Build Coastguard Worker 
304*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("%s Check cache miss rate within %d%%\n",
305*053f45beSAndroid Build Coastguard Worker 		       ret ? "Fail:" : "Pass:", max_diff_percent);
306*053f45beSAndroid Build Coastguard Worker 
307*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Percent diff=%d\n", abs((int)diff_percent));
308*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Number of bits: %d\n", no_of_bits);
309*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Average LLC val: %lu\n", avg_llc_val);
310*053f45beSAndroid Build Coastguard Worker 	ksft_print_msg("Cache span (%s): %lu\n", cmt ? "bytes" : "lines",
311*053f45beSAndroid Build Coastguard Worker 		       cache_span);
312*053f45beSAndroid Build Coastguard Worker 
313*053f45beSAndroid Build Coastguard Worker 	return ret;
314*053f45beSAndroid Build Coastguard Worker }
315