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