linux/tools/testing/selftests/resctrl/resctrl_tests.c
<<
>>
Prefs
   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
  16bool is_amd;
  17
  18void 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
  37static 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
  49void tests_cleanup(void)
  50{
  51        mbm_test_cleanup();
  52        mba_test_cleanup();
  53        cmt_test_cleanup();
  54        cat_test_cleanup();
  55}
  56
  57static 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
  76static 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
  95static 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
 112static 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
 128int 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