0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "resctrl.h"
0012
0013 #define BENCHMARK_ARGS 64
0014 #define BENCHMARK_ARG_SIZE 64
0015
0016 static int detect_vendor(void)
0017 {
0018 FILE *inf = fopen("/proc/cpuinfo", "r");
0019 int vendor_id = 0;
0020 char *s = NULL;
0021 char *res;
0022
0023 if (!inf)
0024 return vendor_id;
0025
0026 res = fgrep(inf, "vendor_id");
0027
0028 if (res)
0029 s = strchr(res, ':');
0030
0031 if (s && !strcmp(s, ": GenuineIntel\n"))
0032 vendor_id = ARCH_INTEL;
0033 else if (s && !strcmp(s, ": AuthenticAMD\n"))
0034 vendor_id = ARCH_AMD;
0035
0036 fclose(inf);
0037 free(res);
0038 return vendor_id;
0039 }
0040
0041 int get_vendor(void)
0042 {
0043 static int vendor = -1;
0044
0045 if (vendor == -1)
0046 vendor = detect_vendor();
0047 if (vendor == 0)
0048 ksft_print_msg("Can not get vendor info...\n");
0049
0050 return vendor;
0051 }
0052
0053 static void cmd_help(void)
0054 {
0055 printf("usage: resctrl_tests [-h] [-b \"benchmark_cmd [options]\"] [-t test list] [-n no_of_bits]\n");
0056 printf("\t-b benchmark_cmd [options]: run specified benchmark for MBM, MBA and CMT\n");
0057 printf("\t default benchmark is builtin fill_buf\n");
0058 printf("\t-t test list: run tests specified in the test list, ");
0059 printf("e.g. -t mbm,mba,cmt,cat\n");
0060 printf("\t-n no_of_bits: run cache tests using specified no of bits in cache bit mask\n");
0061 printf("\t-p cpu_no: specify CPU number to run the test. 1 is default\n");
0062 printf("\t-h: help\n");
0063 }
0064
0065 void tests_cleanup(void)
0066 {
0067 mbm_test_cleanup();
0068 mba_test_cleanup();
0069 cmt_test_cleanup();
0070 cat_test_cleanup();
0071 }
0072
0073 static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span,
0074 int cpu_no, char *bw_report)
0075 {
0076 int res;
0077
0078 ksft_print_msg("Starting MBM BW change ...\n");
0079
0080 if (!validate_resctrl_feature_request(MBM_STR)) {
0081 ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n");
0082 return;
0083 }
0084
0085 if (!has_ben)
0086 sprintf(benchmark_cmd[5], "%s", MBA_STR);
0087 res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
0088 ksft_test_result(!res, "MBM: bw change\n");
0089 if ((get_vendor() == ARCH_INTEL) && res)
0090 ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
0091 mbm_test_cleanup();
0092 }
0093
0094 static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
0095 int cpu_no, char *bw_report)
0096 {
0097 int res;
0098
0099 ksft_print_msg("Starting MBA Schemata change ...\n");
0100
0101 if (!validate_resctrl_feature_request(MBA_STR)) {
0102 ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n");
0103 return;
0104 }
0105
0106 if (!has_ben)
0107 sprintf(benchmark_cmd[1], "%d", span);
0108 res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd);
0109 ksft_test_result(!res, "MBA: schemata change\n");
0110 mba_test_cleanup();
0111 }
0112
0113 static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no)
0114 {
0115 int res;
0116
0117 ksft_print_msg("Starting CMT test ...\n");
0118 if (!validate_resctrl_feature_request(CMT_STR)) {
0119 ksft_test_result_skip("Hardware does not support CMT or CMT is disabled\n");
0120 return;
0121 }
0122
0123 if (!has_ben)
0124 sprintf(benchmark_cmd[5], "%s", CMT_STR);
0125 res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd);
0126 ksft_test_result(!res, "CMT: test\n");
0127 if ((get_vendor() == ARCH_INTEL) && res)
0128 ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
0129 cmt_test_cleanup();
0130 }
0131
0132 static void run_cat_test(int cpu_no, int no_of_bits)
0133 {
0134 int res;
0135
0136 ksft_print_msg("Starting CAT test ...\n");
0137
0138 if (!validate_resctrl_feature_request(CAT_STR)) {
0139 ksft_test_result_skip("Hardware does not support CAT or CAT is disabled\n");
0140 return;
0141 }
0142
0143 res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
0144 ksft_test_result(!res, "CAT: test\n");
0145 cat_test_cleanup();
0146 }
0147
0148 int main(int argc, char **argv)
0149 {
0150 bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true;
0151 int c, cpu_no = 1, span = 250, argc_new = argc, i, no_of_bits = 0;
0152 char *benchmark_cmd[BENCHMARK_ARGS], bw_report[64], bm_type[64];
0153 char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE];
0154 int ben_ind, ben_count, tests = 0;
0155 bool cat_test = true;
0156
0157 for (i = 0; i < argc; i++) {
0158 if (strcmp(argv[i], "-b") == 0) {
0159 ben_ind = i + 1;
0160 ben_count = argc - ben_ind;
0161 argc_new = ben_ind - 1;
0162 has_ben = true;
0163 break;
0164 }
0165 }
0166
0167 while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) {
0168 char *token;
0169
0170 switch (c) {
0171 case 't':
0172 token = strtok(optarg, ",");
0173
0174 mbm_test = false;
0175 mba_test = false;
0176 cmt_test = false;
0177 cat_test = false;
0178 while (token) {
0179 if (!strncmp(token, MBM_STR, sizeof(MBM_STR))) {
0180 mbm_test = true;
0181 tests++;
0182 } else if (!strncmp(token, MBA_STR, sizeof(MBA_STR))) {
0183 mba_test = true;
0184 tests++;
0185 } else if (!strncmp(token, CMT_STR, sizeof(CMT_STR))) {
0186 cmt_test = true;
0187 tests++;
0188 } else if (!strncmp(token, CAT_STR, sizeof(CAT_STR))) {
0189 cat_test = true;
0190 tests++;
0191 } else {
0192 printf("invalid argument\n");
0193
0194 return -1;
0195 }
0196 token = strtok(NULL, ",");
0197 }
0198 break;
0199 case 'p':
0200 cpu_no = atoi(optarg);
0201 break;
0202 case 'n':
0203 no_of_bits = atoi(optarg);
0204 if (no_of_bits <= 0) {
0205 printf("Bail out! invalid argument for no_of_bits\n");
0206 return -1;
0207 }
0208 break;
0209 case 'h':
0210 cmd_help();
0211
0212 return 0;
0213 default:
0214 printf("invalid argument\n");
0215
0216 return -1;
0217 }
0218 }
0219
0220 ksft_print_header();
0221
0222
0223
0224
0225
0226
0227 if (geteuid() != 0)
0228 return ksft_exit_skip("Not running as root. Skipping...\n");
0229
0230 if (has_ben) {
0231
0232 for (i = ben_ind; i < argc; i++) {
0233 benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i];
0234 sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]);
0235 }
0236 benchmark_cmd[ben_count] = NULL;
0237 } else {
0238
0239 for (i = 0; i < 6; i++)
0240 benchmark_cmd[i] = benchmark_cmd_area[i];
0241
0242 strcpy(benchmark_cmd[0], "fill_buf");
0243 sprintf(benchmark_cmd[1], "%d", span);
0244 strcpy(benchmark_cmd[2], "1");
0245 strcpy(benchmark_cmd[3], "1");
0246 strcpy(benchmark_cmd[4], "0");
0247 strcpy(benchmark_cmd[5], "");
0248 benchmark_cmd[6] = NULL;
0249 }
0250
0251 sprintf(bw_report, "reads");
0252 sprintf(bm_type, "fill_buf");
0253
0254 if (!check_resctrlfs_support())
0255 return ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n");
0256
0257 filter_dmesg();
0258
0259 ksft_set_plan(tests ? : 4);
0260
0261 if ((get_vendor() == ARCH_INTEL) && mbm_test)
0262 run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
0263
0264 if ((get_vendor() == ARCH_INTEL) && mba_test)
0265 run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
0266
0267 if (cmt_test)
0268 run_cmt_test(has_ben, benchmark_cmd, cpu_no);
0269
0270 if (cat_test)
0271 run_cat_test(cpu_no, no_of_bits);
0272
0273 umount_resctrlfs();
0274
0275 return ksft_exit_pass();
0276 }