~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/resctrl/cmt_test.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Cache Monitoring Technology (CMT) test
  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 #include <unistd.h>
 13 
 14 #define RESULT_FILE_NAME        "result_cmt"
 15 #define NUM_OF_RUNS             5
 16 #define MAX_DIFF                2000000
 17 #define MAX_DIFF_PERCENT        15
 18 
 19 #define CON_MON_LCC_OCCUP_PATH          \
 20         "%s/%s/mon_data/mon_L3_%02d/llc_occupancy"
 21 
 22 static int cmt_init(const struct resctrl_val_param *param, int domain_id)
 23 {
 24         sprintf(llc_occup_path, CON_MON_LCC_OCCUP_PATH, RESCTRL_PATH,
 25                 param->ctrlgrp, domain_id);
 26 
 27         return 0;
 28 }
 29 
 30 static int cmt_setup(const struct resctrl_test *test,
 31                      const struct user_params *uparams,
 32                      struct resctrl_val_param *p)
 33 {
 34         /* Run NUM_OF_RUNS times */
 35         if (p->num_of_runs >= NUM_OF_RUNS)
 36                 return END_OF_TESTS;
 37 
 38         p->num_of_runs++;
 39 
 40         return 0;
 41 }
 42 
 43 static int cmt_measure(const struct user_params *uparams,
 44                        struct resctrl_val_param *param, pid_t bm_pid)
 45 {
 46         sleep(1);
 47         return measure_llc_resctrl(param->filename, bm_pid);
 48 }
 49 
 50 static int show_results_info(unsigned long sum_llc_val, int no_of_bits,
 51                              unsigned long cache_span, unsigned long max_diff,
 52                              unsigned long max_diff_percent, unsigned long num_of_runs,
 53                              bool platform)
 54 {
 55         unsigned long avg_llc_val = 0;
 56         float diff_percent;
 57         long avg_diff = 0;
 58         int ret;
 59 
 60         avg_llc_val = sum_llc_val / num_of_runs;
 61         avg_diff = (long)(cache_span - avg_llc_val);
 62         diff_percent = ((float)cache_span - avg_llc_val) / cache_span * 100;
 63 
 64         ret = platform && abs((int)diff_percent) > max_diff_percent &&
 65               labs(avg_diff) > max_diff;
 66 
 67         ksft_print_msg("%s Check cache miss rate within %lu%%\n",
 68                        ret ? "Fail:" : "Pass:", max_diff_percent);
 69 
 70         ksft_print_msg("Percent diff=%d\n", abs((int)diff_percent));
 71 
 72         show_cache_info(no_of_bits, avg_llc_val, cache_span, false);
 73 
 74         return ret;
 75 }
 76 
 77 static int check_results(struct resctrl_val_param *param, size_t span, int no_of_bits)
 78 {
 79         char *token_array[8], temp[512];
 80         unsigned long sum_llc_occu_resc = 0;
 81         int runs = 0;
 82         FILE *fp;
 83 
 84         ksft_print_msg("Checking for pass/fail\n");
 85         fp = fopen(param->filename, "r");
 86         if (!fp) {
 87                 ksft_perror("Error in opening file");
 88 
 89                 return -1;
 90         }
 91 
 92         while (fgets(temp, sizeof(temp), fp)) {
 93                 char *token = strtok(temp, ":\t");
 94                 int fields = 0;
 95 
 96                 while (token) {
 97                         token_array[fields++] = token;
 98                         token = strtok(NULL, ":\t");
 99                 }
100 
101                 /* Field 3 is llc occ resc value */
102                 if (runs > 0)
103                         sum_llc_occu_resc += strtoul(token_array[3], NULL, 0);
104                 runs++;
105         }
106         fclose(fp);
107 
108         return show_results_info(sum_llc_occu_resc, no_of_bits, span,
109                                  MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, true);
110 }
111 
112 static void cmt_test_cleanup(void)
113 {
114         remove(RESULT_FILE_NAME);
115 }
116 
117 static int cmt_run_test(const struct resctrl_test *test, const struct user_params *uparams)
118 {
119         const char * const *cmd = uparams->benchmark_cmd;
120         const char *new_cmd[BENCHMARK_ARGS];
121         unsigned long cache_total_size = 0;
122         int n = uparams->bits ? : 5;
123         unsigned long long_mask;
124         char *span_str = NULL;
125         int count_of_bits;
126         size_t span;
127         int ret, i;
128 
129         ret = get_full_cbm("L3", &long_mask);
130         if (ret)
131                 return ret;
132 
133         ret = get_cache_size(uparams->cpu, "L3", &cache_total_size);
134         if (ret)
135                 return ret;
136         ksft_print_msg("Cache size :%lu\n", cache_total_size);
137 
138         count_of_bits = count_bits(long_mask);
139 
140         if (n < 1 || n > count_of_bits) {
141                 ksft_print_msg("Invalid input value for numbr_of_bits n!\n");
142                 ksft_print_msg("Please enter value in range 1 to %d\n", count_of_bits);
143                 return -1;
144         }
145 
146         struct resctrl_val_param param = {
147                 .ctrlgrp        = "c1",
148                 .filename       = RESULT_FILE_NAME,
149                 .mask           = ~(long_mask << n) & long_mask,
150                 .num_of_runs    = 0,
151                 .init           = cmt_init,
152                 .setup          = cmt_setup,
153                 .measure        = cmt_measure,
154         };
155 
156         span = cache_portion_size(cache_total_size, param.mask, long_mask);
157 
158         if (strcmp(cmd[0], "fill_buf") == 0) {
159                 /* Duplicate the command to be able to replace span in it */
160                 for (i = 0; uparams->benchmark_cmd[i]; i++)
161                         new_cmd[i] = uparams->benchmark_cmd[i];
162                 new_cmd[i] = NULL;
163 
164                 ret = asprintf(&span_str, "%zu", span);
165                 if (ret < 0)
166                         return -1;
167                 new_cmd[1] = span_str;
168                 cmd = new_cmd;
169         }
170 
171         remove(RESULT_FILE_NAME);
172 
173         ret = resctrl_val(test, uparams, cmd, &param);
174         if (ret)
175                 goto out;
176 
177         ret = check_results(&param, span, n);
178         if (ret && (get_vendor() == ARCH_INTEL))
179                 ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
180 
181 out:
182         free(span_str);
183 
184         return ret;
185 }
186 
187 static bool cmt_feature_check(const struct resctrl_test *test)
188 {
189         return test_resource_feature_check(test) &&
190                resctrl_mon_feature_exists("L3_MON", "llc_occupancy");
191 }
192 
193 struct resctrl_test cmt_test = {
194         .name = "CMT",
195         .resource = "L3",
196         .feature_check = cmt_feature_check,
197         .run_test = cmt_run_test,
198         .cleanup = cmt_test_cleanup,
199 };
200 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php