xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/resctrl/resctrl_tests.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Resctrl tests
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2018 Intel Corporation
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Authors:
8*4882a593Smuzhiyun  *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
9*4882a593Smuzhiyun  *    Fenghua Yu <fenghua.yu@intel.com>
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun #include "resctrl.h"
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define BENCHMARK_ARGS		64
14*4882a593Smuzhiyun #define BENCHMARK_ARG_SIZE	64
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun bool is_amd;
17*4882a593Smuzhiyun 
detect_amd(void)18*4882a593Smuzhiyun void detect_amd(void)
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun 	FILE *inf = fopen("/proc/cpuinfo", "r");
21*4882a593Smuzhiyun 	char *res;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	if (!inf)
24*4882a593Smuzhiyun 		return;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 	res = fgrep(inf, "vendor_id");
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	if (res) {
29*4882a593Smuzhiyun 		char *s = strchr(res, ':');
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 		is_amd = s && !strcmp(s, ": AuthenticAMD\n");
32*4882a593Smuzhiyun 		free(res);
33*4882a593Smuzhiyun 	}
34*4882a593Smuzhiyun 	fclose(inf);
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun 
cmd_help(void)37*4882a593Smuzhiyun static void cmd_help(void)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	printf("usage: resctrl_tests [-h] [-b \"benchmark_cmd [options]\"] [-t test list] [-n no_of_bits]\n");
40*4882a593Smuzhiyun 	printf("\t-b benchmark_cmd [options]: run specified benchmark for MBM, MBA and CQM");
41*4882a593Smuzhiyun 	printf("\t default benchmark is builtin fill_buf\n");
42*4882a593Smuzhiyun 	printf("\t-t test list: run tests specified in the test list, ");
43*4882a593Smuzhiyun 	printf("e.g. -t mbm,mba,cqm,cat\n");
44*4882a593Smuzhiyun 	printf("\t-n no_of_bits: run cache tests using specified no of bits in cache bit mask\n");
45*4882a593Smuzhiyun 	printf("\t-p cpu_no: specify CPU number to run the test. 1 is default\n");
46*4882a593Smuzhiyun 	printf("\t-h: help\n");
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
tests_cleanup(void)49*4882a593Smuzhiyun void tests_cleanup(void)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	mbm_test_cleanup();
52*4882a593Smuzhiyun 	mba_test_cleanup();
53*4882a593Smuzhiyun 	cqm_test_cleanup();
54*4882a593Smuzhiyun 	cat_test_cleanup();
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
main(int argc,char ** argv)57*4882a593Smuzhiyun int main(int argc, char **argv)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	bool has_ben = false, mbm_test = true, mba_test = true, cqm_test = true;
60*4882a593Smuzhiyun 	int res, c, cpu_no = 1, span = 250, argc_new = argc, i, no_of_bits = 5;
61*4882a593Smuzhiyun 	char *benchmark_cmd[BENCHMARK_ARGS], bw_report[64], bm_type[64];
62*4882a593Smuzhiyun 	char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE];
63*4882a593Smuzhiyun 	int ben_ind, ben_count;
64*4882a593Smuzhiyun 	bool cat_test = true;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	for (i = 0; i < argc; i++) {
67*4882a593Smuzhiyun 		if (strcmp(argv[i], "-b") == 0) {
68*4882a593Smuzhiyun 			ben_ind = i + 1;
69*4882a593Smuzhiyun 			ben_count = argc - ben_ind;
70*4882a593Smuzhiyun 			argc_new = ben_ind - 1;
71*4882a593Smuzhiyun 			has_ben = true;
72*4882a593Smuzhiyun 			break;
73*4882a593Smuzhiyun 		}
74*4882a593Smuzhiyun 	}
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) {
77*4882a593Smuzhiyun 		char *token;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 		switch (c) {
80*4882a593Smuzhiyun 		case 't':
81*4882a593Smuzhiyun 			token = strtok(optarg, ",");
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 			mbm_test = false;
84*4882a593Smuzhiyun 			mba_test = false;
85*4882a593Smuzhiyun 			cqm_test = false;
86*4882a593Smuzhiyun 			cat_test = false;
87*4882a593Smuzhiyun 			while (token) {
88*4882a593Smuzhiyun 				if (!strncmp(token, MBM_STR, sizeof(MBM_STR))) {
89*4882a593Smuzhiyun 					mbm_test = true;
90*4882a593Smuzhiyun 				} else if (!strncmp(token, MBA_STR, sizeof(MBA_STR))) {
91*4882a593Smuzhiyun 					mba_test = true;
92*4882a593Smuzhiyun 				} else if (!strncmp(token, CQM_STR, sizeof(CQM_STR))) {
93*4882a593Smuzhiyun 					cqm_test = true;
94*4882a593Smuzhiyun 				} else if (!strncmp(token, CAT_STR, sizeof(CAT_STR))) {
95*4882a593Smuzhiyun 					cat_test = true;
96*4882a593Smuzhiyun 				} else {
97*4882a593Smuzhiyun 					printf("invalid argument\n");
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 					return -1;
100*4882a593Smuzhiyun 				}
101*4882a593Smuzhiyun 				token = strtok(NULL, ",");
102*4882a593Smuzhiyun 			}
103*4882a593Smuzhiyun 			break;
104*4882a593Smuzhiyun 		case 'p':
105*4882a593Smuzhiyun 			cpu_no = atoi(optarg);
106*4882a593Smuzhiyun 			break;
107*4882a593Smuzhiyun 		case 'n':
108*4882a593Smuzhiyun 			no_of_bits = atoi(optarg);
109*4882a593Smuzhiyun 			break;
110*4882a593Smuzhiyun 		case 'h':
111*4882a593Smuzhiyun 			cmd_help();
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 			return 0;
114*4882a593Smuzhiyun 		default:
115*4882a593Smuzhiyun 			printf("invalid argument\n");
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 			return -1;
118*4882a593Smuzhiyun 		}
119*4882a593Smuzhiyun 	}
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	printf("TAP version 13\n");
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	/*
124*4882a593Smuzhiyun 	 * Typically we need root privileges, because:
125*4882a593Smuzhiyun 	 * 1. We write to resctrl FS
126*4882a593Smuzhiyun 	 * 2. We execute perf commands
127*4882a593Smuzhiyun 	 */
128*4882a593Smuzhiyun 	if (geteuid() != 0)
129*4882a593Smuzhiyun 		printf("# WARNING: not running as root, tests may fail.\n");
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	/* Detect AMD vendor */
132*4882a593Smuzhiyun 	detect_amd();
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	if (has_ben) {
135*4882a593Smuzhiyun 		/* Extract benchmark command from command line. */
136*4882a593Smuzhiyun 		for (i = ben_ind; i < argc; i++) {
137*4882a593Smuzhiyun 			benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i];
138*4882a593Smuzhiyun 			sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]);
139*4882a593Smuzhiyun 		}
140*4882a593Smuzhiyun 		benchmark_cmd[ben_count] = NULL;
141*4882a593Smuzhiyun 	} else {
142*4882a593Smuzhiyun 		/* If no benchmark is given by "-b" argument, use fill_buf. */
143*4882a593Smuzhiyun 		for (i = 0; i < 6; i++)
144*4882a593Smuzhiyun 			benchmark_cmd[i] = benchmark_cmd_area[i];
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 		strcpy(benchmark_cmd[0], "fill_buf");
147*4882a593Smuzhiyun 		sprintf(benchmark_cmd[1], "%d", span);
148*4882a593Smuzhiyun 		strcpy(benchmark_cmd[2], "1");
149*4882a593Smuzhiyun 		strcpy(benchmark_cmd[3], "1");
150*4882a593Smuzhiyun 		strcpy(benchmark_cmd[4], "0");
151*4882a593Smuzhiyun 		strcpy(benchmark_cmd[5], "");
152*4882a593Smuzhiyun 		benchmark_cmd[6] = NULL;
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	sprintf(bw_report, "reads");
156*4882a593Smuzhiyun 	sprintf(bm_type, "fill_buf");
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	check_resctrlfs_support();
159*4882a593Smuzhiyun 	filter_dmesg();
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	if (!is_amd && mbm_test) {
162*4882a593Smuzhiyun 		printf("# Starting MBM BW change ...\n");
163*4882a593Smuzhiyun 		if (!has_ben)
164*4882a593Smuzhiyun 			sprintf(benchmark_cmd[5], "%s", MBA_STR);
165*4882a593Smuzhiyun 		res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
166*4882a593Smuzhiyun 		printf("%sok MBM: bw change\n", res ? "not " : "");
167*4882a593Smuzhiyun 		mbm_test_cleanup();
168*4882a593Smuzhiyun 		tests_run++;
169*4882a593Smuzhiyun 	}
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	if (!is_amd && mba_test) {
172*4882a593Smuzhiyun 		printf("# Starting MBA Schemata change ...\n");
173*4882a593Smuzhiyun 		if (!has_ben)
174*4882a593Smuzhiyun 			sprintf(benchmark_cmd[1], "%d", span);
175*4882a593Smuzhiyun 		res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd);
176*4882a593Smuzhiyun 		printf("%sok MBA: schemata change\n", res ? "not " : "");
177*4882a593Smuzhiyun 		mba_test_cleanup();
178*4882a593Smuzhiyun 		tests_run++;
179*4882a593Smuzhiyun 	}
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	if (cqm_test) {
182*4882a593Smuzhiyun 		printf("# Starting CQM test ...\n");
183*4882a593Smuzhiyun 		if (!has_ben)
184*4882a593Smuzhiyun 			sprintf(benchmark_cmd[5], "%s", CQM_STR);
185*4882a593Smuzhiyun 		res = cqm_resctrl_val(cpu_no, no_of_bits, benchmark_cmd);
186*4882a593Smuzhiyun 		printf("%sok CQM: test\n", res ? "not " : "");
187*4882a593Smuzhiyun 		cqm_test_cleanup();
188*4882a593Smuzhiyun 		tests_run++;
189*4882a593Smuzhiyun 	}
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	if (cat_test) {
192*4882a593Smuzhiyun 		printf("# Starting CAT test ...\n");
193*4882a593Smuzhiyun 		res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
194*4882a593Smuzhiyun 		printf("%sok CAT: test\n", res ? "not " : "");
195*4882a593Smuzhiyun 		tests_run++;
196*4882a593Smuzhiyun 		cat_test_cleanup();
197*4882a593Smuzhiyun 	}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	printf("1..%d\n", tests_run);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	return 0;
202*4882a593Smuzhiyun }
203