1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Resctrl tests 4 * 5 * Copyright (C) 2018 Intel Corporation 6 * 7 * Authors: 8 * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>, 9 * Fenghua Yu <fenghua.yu@intel.com> 10 */ 11 #include "resctrl.h" 12 13 #define BENCHMARK_ARGS 64 14 #define BENCHMARK_ARG_SIZE 64 15 16 bool is_amd; 17 18 void detect_amd(void) 19 { 20 FILE *inf = fopen("/proc/cpuinfo", "r"); 21 char *res; 22 23 if (!inf) 24 return; 25 26 res = fgrep(inf, "vendor_id"); 27 28 if (res) { 29 char *s = strchr(res, ':'); 30 31 is_amd = s && !strcmp(s, ": AuthenticAMD\n"); 32 free(res); 33 } 34 fclose(inf); 35 } 36 37 static void cmd_help(void) 38 { 39 printf("usage: resctrl_tests [-h] [-b \"benchmark_cmd [options]\"] [-t test list] [-n no_of_bits]\n"); 40 printf("\t-b benchmark_cmd [options]: run specified benchmark for MBM, MBA and CMT\n"); 41 printf("\t default benchmark is builtin fill_buf\n"); 42 printf("\t-t test list: run tests specified in the test list, "); 43 printf("e.g. -t mbm,mba,cmt,cat\n"); 44 printf("\t-n no_of_bits: run cache tests using specified no of bits in cache bit mask\n"); 45 printf("\t-p cpu_no: specify CPU number to run the test. 1 is default\n"); 46 printf("\t-h: help\n"); 47 } 48 49 void tests_cleanup(void) 50 { 51 mbm_test_cleanup(); 52 mba_test_cleanup(); 53 cmt_test_cleanup(); 54 cat_test_cleanup(); 55 } 56 57 static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span, 58 int cpu_no, char *bw_report) 59 { 60 int res; 61 62 ksft_print_msg("Starting MBM BW change ...\n"); 63 64 if (!validate_resctrl_feature_request(MBM_STR)) { 65 ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n"); 66 return; 67 } 68 69 if (!has_ben) 70 sprintf(benchmark_cmd[5], "%s", MBA_STR); 71 res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd); 72 ksft_test_result(!res, "MBM: bw change\n"); 73 mbm_test_cleanup(); 74 } 75 76 static void run_mba_test(bool has_ben, char **benchmark_cmd, int span, 77 int cpu_no, char *bw_report) 78 { 79 int res; 80 81 ksft_print_msg("Starting MBA Schemata change ...\n"); 82 83 if (!validate_resctrl_feature_request(MBA_STR)) { 84 ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n"); 85 return; 86 } 87 88 if (!has_ben) 89 sprintf(benchmark_cmd[1], "%d", span); 90 res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd); 91 ksft_test_result(!res, "MBA: schemata change\n"); 92 mba_test_cleanup(); 93 } 94 95 static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no) 96 { 97 int res; 98 99 ksft_print_msg("Starting CMT test ...\n"); 100 if (!validate_resctrl_feature_request(CMT_STR)) { 101 ksft_test_result_skip("Hardware does not support CMT or CMT is disabled\n"); 102 return; 103 } 104 105 if (!has_ben) 106 sprintf(benchmark_cmd[5], "%s", CMT_STR); 107 res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd); 108 ksft_test_result(!res, "CMT: test\n"); 109 cmt_test_cleanup(); 110 } 111 112 static void run_cat_test(int cpu_no, int no_of_bits) 113 { 114 int res; 115 116 ksft_print_msg("Starting CAT test ...\n"); 117 118 if (!validate_resctrl_feature_request(CAT_STR)) { 119 ksft_test_result_skip("Hardware does not support CAT or CAT is disabled\n"); 120 return; 121 } 122 123 res = cat_perf_miss_val(cpu_no, no_of_bits, "L3"); 124 ksft_test_result(!res, "CAT: test\n"); 125 cat_test_cleanup(); 126 } 127 128 int main(int argc, char **argv) 129 { 130 bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true; 131 int c, cpu_no = 1, span = 250, argc_new = argc, i, no_of_bits = 0; 132 char *benchmark_cmd[BENCHMARK_ARGS], bw_report[64], bm_type[64]; 133 char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE]; 134 int ben_ind, ben_count, tests = 0; 135 bool cat_test = true; 136 137 for (i = 0; i < argc; i++) { 138 if (strcmp(argv[i], "-b") == 0) { 139 ben_ind = i + 1; 140 ben_count = argc - ben_ind; 141 argc_new = ben_ind - 1; 142 has_ben = true; 143 break; 144 } 145 } 146 147 while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) { 148 char *token; 149 150 switch (c) { 151 case 't': 152 token = strtok(optarg, ","); 153 154 mbm_test = false; 155 mba_test = false; 156 cmt_test = false; 157 cat_test = false; 158 while (token) { 159 if (!strncmp(token, MBM_STR, sizeof(MBM_STR))) { 160 mbm_test = true; 161 tests++; 162 } else if (!strncmp(token, MBA_STR, sizeof(MBA_STR))) { 163 mba_test = true; 164 tests++; 165 } else if (!strncmp(token, CMT_STR, sizeof(CMT_STR))) { 166 cmt_test = true; 167 tests++; 168 } else if (!strncmp(token, CAT_STR, sizeof(CAT_STR))) { 169 cat_test = true; 170 tests++; 171 } else { 172 printf("invalid argument\n"); 173 174 return -1; 175 } 176 token = strtok(NULL, ","); 177 } 178 break; 179 case 'p': 180 cpu_no = atoi(optarg); 181 break; 182 case 'n': 183 no_of_bits = atoi(optarg); 184 if (no_of_bits <= 0) { 185 printf("Bail out! invalid argument for no_of_bits\n"); 186 return -1; 187 } 188 break; 189 case 'h': 190 cmd_help(); 191 192 return 0; 193 default: 194 printf("invalid argument\n"); 195 196 return -1; 197 } 198 } 199 200 ksft_print_header(); 201 202 /* 203 * Typically we need root privileges, because: 204 * 1. We write to resctrl FS 205 * 2. We execute perf commands 206 */ 207 if (geteuid() != 0) 208 return ksft_exit_fail_msg("Not running as root, abort testing.\n"); 209 210 /* Detect AMD vendor */ 211 detect_amd(); 212 213 if (has_ben) { 214 /* Extract benchmark command from command line. */ 215 for (i = ben_ind; i < argc; i++) { 216 benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i]; 217 sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]); 218 } 219 benchmark_cmd[ben_count] = NULL; 220 } else { 221 /* If no benchmark is given by "-b" argument, use fill_buf. */ 222 for (i = 0; i < 6; i++) 223 benchmark_cmd[i] = benchmark_cmd_area[i]; 224 225 strcpy(benchmark_cmd[0], "fill_buf"); 226 sprintf(benchmark_cmd[1], "%d", span); 227 strcpy(benchmark_cmd[2], "1"); 228 strcpy(benchmark_cmd[3], "1"); 229 strcpy(benchmark_cmd[4], "0"); 230 strcpy(benchmark_cmd[5], ""); 231 benchmark_cmd[6] = NULL; 232 } 233 234 sprintf(bw_report, "reads"); 235 sprintf(bm_type, "fill_buf"); 236 237 if (!check_resctrlfs_support()) 238 return ksft_exit_fail_msg("resctrl FS does not exist\n"); 239 240 filter_dmesg(); 241 242 ksft_set_plan(tests ? : 4); 243 244 if (!is_amd && mbm_test) 245 run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report); 246 247 if (!is_amd && mba_test) 248 run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report); 249 250 if (cmt_test) 251 run_cmt_test(has_ben, benchmark_cmd, cpu_no); 252 253 if (cat_test) 254 run_cat_test(cpu_no, no_of_bits); 255 256 umount_resctrlfs(); 257 258 return ksft_exit_pass(); 259 } 260