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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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  * Memory Bandwidth Allocation (MBA) 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 
 13 #define RESULT_FILE_NAME        "result_mba"
 14 #define NUM_OF_RUNS             5
 15 #define MAX_DIFF_PERCENT        8
 16 #define ALLOCATION_MAX          100
 17 #define ALLOCATION_MIN          10
 18 #define ALLOCATION_STEP         10
 19 
 20 static int mba_init(const struct resctrl_val_param *param, int domain_id)
 21 {
 22         int ret;
 23 
 24         ret = initialize_mem_bw_imc();
 25         if (ret)
 26                 return ret;
 27 
 28         initialize_mem_bw_resctrl(param, domain_id);
 29 
 30         return 0;
 31 }
 32 
 33 /*
 34  * Change schemata percentage from 100 to 10%. Write schemata to specified
 35  * con_mon grp, mon_grp in resctrl FS.
 36  * For each allocation, run 5 times in order to get average values.
 37  */
 38 static int mba_setup(const struct resctrl_test *test,
 39                      const struct user_params *uparams,
 40                      struct resctrl_val_param *p)
 41 {
 42         static int runs_per_allocation, allocation = 100;
 43         char allocation_str[64];
 44         int ret;
 45 
 46         if (runs_per_allocation >= NUM_OF_RUNS)
 47                 runs_per_allocation = 0;
 48 
 49         /* Only set up schemata once every NUM_OF_RUNS of allocations */
 50         if (runs_per_allocation++ != 0)
 51                 return 0;
 52 
 53         if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX)
 54                 return END_OF_TESTS;
 55 
 56         sprintf(allocation_str, "%d", allocation);
 57 
 58         ret = write_schemata(p->ctrlgrp, allocation_str, uparams->cpu, test->resource);
 59         if (ret < 0)
 60                 return ret;
 61 
 62         allocation -= ALLOCATION_STEP;
 63 
 64         return 0;
 65 }
 66 
 67 static int mba_measure(const struct user_params *uparams,
 68                        struct resctrl_val_param *param, pid_t bm_pid)
 69 {
 70         return measure_mem_bw(uparams, param, bm_pid, "reads");
 71 }
 72 
 73 static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
 74 {
 75         int allocation, runs;
 76         bool ret = false;
 77 
 78         ksft_print_msg("Results are displayed in (MB)\n");
 79         /* Memory bandwidth from 100% down to 10% */
 80         for (allocation = 0; allocation < ALLOCATION_MAX / ALLOCATION_STEP;
 81              allocation++) {
 82                 unsigned long sum_bw_imc = 0, sum_bw_resc = 0;
 83                 long avg_bw_imc, avg_bw_resc;
 84                 int avg_diff_per;
 85                 float avg_diff;
 86 
 87                 /*
 88                  * The first run is discarded due to inaccurate value from
 89                  * phase transition.
 90                  */
 91                 for (runs = NUM_OF_RUNS * allocation + 1;
 92                      runs < NUM_OF_RUNS * allocation + NUM_OF_RUNS ; runs++) {
 93                         sum_bw_imc += bw_imc[runs];
 94                         sum_bw_resc += bw_resc[runs];
 95                 }
 96 
 97                 avg_bw_imc = sum_bw_imc / (NUM_OF_RUNS - 1);
 98                 avg_bw_resc = sum_bw_resc / (NUM_OF_RUNS - 1);
 99                 avg_diff = (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc;
100                 avg_diff_per = (int)(avg_diff * 100);
101 
102                 ksft_print_msg("%s Check MBA diff within %d%% for schemata %u\n",
103                                avg_diff_per > MAX_DIFF_PERCENT ?
104                                "Fail:" : "Pass:",
105                                MAX_DIFF_PERCENT,
106                                ALLOCATION_MAX - ALLOCATION_STEP * allocation);
107 
108                 ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per);
109                 ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc);
110                 ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc);
111                 if (avg_diff_per > MAX_DIFF_PERCENT)
112                         ret = true;
113         }
114 
115         ksft_print_msg("%s Check schemata change using MBA\n",
116                        ret ? "Fail:" : "Pass:");
117         if (ret)
118                 ksft_print_msg("At least one test failed\n");
119 
120         return ret;
121 }
122 
123 static int check_results(void)
124 {
125         char *token_array[8], output[] = RESULT_FILE_NAME, temp[512];
126         unsigned long bw_imc[1024], bw_resc[1024];
127         int runs;
128         FILE *fp;
129 
130         fp = fopen(output, "r");
131         if (!fp) {
132                 ksft_perror(output);
133 
134                 return -1;
135         }
136 
137         runs = 0;
138         while (fgets(temp, sizeof(temp), fp)) {
139                 char *token = strtok(temp, ":\t");
140                 int fields = 0;
141 
142                 while (token) {
143                         token_array[fields++] = token;
144                         token = strtok(NULL, ":\t");
145                 }
146 
147                 /* Field 3 is perf imc value */
148                 bw_imc[runs] = strtoul(token_array[3], NULL, 0);
149                 /* Field 5 is resctrl value */
150                 bw_resc[runs] = strtoul(token_array[5], NULL, 0);
151                 runs++;
152         }
153 
154         fclose(fp);
155 
156         return show_mba_info(bw_imc, bw_resc);
157 }
158 
159 static void mba_test_cleanup(void)
160 {
161         remove(RESULT_FILE_NAME);
162 }
163 
164 static int mba_run_test(const struct resctrl_test *test, const struct user_params *uparams)
165 {
166         struct resctrl_val_param param = {
167                 .ctrlgrp        = "c1",
168                 .filename       = RESULT_FILE_NAME,
169                 .init           = mba_init,
170                 .setup          = mba_setup,
171                 .measure        = mba_measure,
172         };
173         int ret;
174 
175         remove(RESULT_FILE_NAME);
176 
177         ret = resctrl_val(test, uparams, uparams->benchmark_cmd, &param);
178         if (ret)
179                 return ret;
180 
181         ret = check_results();
182 
183         return ret;
184 }
185 
186 static bool mba_feature_check(const struct resctrl_test *test)
187 {
188         return test_resource_feature_check(test) &&
189                resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes");
190 }
191 
192 struct resctrl_test mba_test = {
193         .name = "MBA",
194         .resource = "MB",
195         .vendor_specific = ARCH_INTEL,
196         .feature_check = mba_feature_check,
197         .run_test = mba_run_test,
198         .cleanup = mba_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