Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Resctrl tests
0004  *
0005  * Copyright (C) 2018 Intel Corporation
0006  *
0007  * Authors:
0008  *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
0009  *    Fenghua Yu <fenghua.yu@intel.com>
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      * Typically we need root privileges, because:
0224      * 1. We write to resctrl FS
0225      * 2. We execute perf commands
0226      */
0227     if (geteuid() != 0)
0228         return ksft_exit_skip("Not running as root. Skipping...\n");
0229 
0230     if (has_ben) {
0231         /* Extract benchmark command from command line. */
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         /* If no benchmark is given by "-b" argument, use fill_buf. */
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 }