drm/bridge: adv7511: Switch to atomic operations
[drm/drm-misc.git] / tools / testing / selftests / resctrl / mba_test.c
blob536d9089d2f6c87ebd139906c342ecb5afad2ebc
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Memory Bandwidth Allocation (MBA) test
5 * Copyright (C) 2018 Intel Corporation
7 * Authors:
8 * Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
9 * Fenghua Yu <fenghua.yu@intel.com>
11 #include "resctrl.h"
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
20 static int mba_init(const struct resctrl_val_param *param, int domain_id)
22 int ret;
24 ret = initialize_read_mem_bw_imc();
25 if (ret)
26 return ret;
28 initialize_mem_bw_resctrl(param, domain_id);
30 return 0;
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.
38 static int mba_setup(const struct resctrl_test *test,
39 const struct user_params *uparams,
40 struct resctrl_val_param *p)
42 static unsigned int allocation = ALLOCATION_MIN;
43 static int runs_per_allocation;
44 char allocation_str[64];
45 int ret;
47 if (runs_per_allocation >= NUM_OF_RUNS)
48 runs_per_allocation = 0;
50 /* Only set up schemata once every NUM_OF_RUNS of allocations */
51 if (runs_per_allocation++ != 0)
52 return 0;
54 if (allocation > ALLOCATION_MAX)
55 return END_OF_TESTS;
57 sprintf(allocation_str, "%d", allocation);
59 ret = write_schemata(p->ctrlgrp, allocation_str, uparams->cpu, test->resource);
60 if (ret < 0)
61 return ret;
63 allocation += ALLOCATION_STEP;
65 return 0;
68 static int mba_measure(const struct user_params *uparams,
69 struct resctrl_val_param *param, pid_t bm_pid)
71 return measure_read_mem_bw(uparams, param, bm_pid);
74 static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
76 unsigned int allocation;
77 bool ret = false;
78 int runs;
80 ksft_print_msg("Results are displayed in (MB)\n");
81 /* Memory bandwidth from 100% down to 10% */
82 for (allocation = 0; allocation < ALLOCATION_MAX / ALLOCATION_STEP;
83 allocation++) {
84 unsigned long sum_bw_imc = 0, sum_bw_resc = 0;
85 long avg_bw_imc, avg_bw_resc;
86 int avg_diff_per;
87 float avg_diff;
89 for (runs = NUM_OF_RUNS * allocation;
90 runs < NUM_OF_RUNS * allocation + NUM_OF_RUNS ; runs++) {
91 sum_bw_imc += bw_imc[runs];
92 sum_bw_resc += bw_resc[runs];
95 avg_bw_imc = sum_bw_imc / NUM_OF_RUNS;
96 avg_bw_resc = sum_bw_resc / NUM_OF_RUNS;
97 if (avg_bw_imc < THROTTLE_THRESHOLD || avg_bw_resc < THROTTLE_THRESHOLD) {
98 ksft_print_msg("Bandwidth below threshold (%d MiB). Dropping results from MBA schemata %u.\n",
99 THROTTLE_THRESHOLD,
100 ALLOCATION_MIN + ALLOCATION_STEP * allocation);
101 continue;
104 avg_diff = (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc;
105 avg_diff_per = (int)(avg_diff * 100);
107 ksft_print_msg("%s Check MBA diff within %d%% for schemata %u\n",
108 avg_diff_per > MAX_DIFF_PERCENT ?
109 "Fail:" : "Pass:",
110 MAX_DIFF_PERCENT,
111 ALLOCATION_MIN + ALLOCATION_STEP * allocation);
113 ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per);
114 ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc);
115 ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc);
116 if (avg_diff_per > MAX_DIFF_PERCENT)
117 ret = true;
120 ksft_print_msg("%s Check schemata change using MBA\n",
121 ret ? "Fail:" : "Pass:");
122 if (ret)
123 ksft_print_msg("At least one test failed\n");
125 return ret;
128 static int check_results(void)
130 unsigned long bw_resc[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP];
131 unsigned long bw_imc[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP];
132 char *token_array[8], output[] = RESULT_FILE_NAME, temp[512];
133 int runs;
134 FILE *fp;
136 fp = fopen(output, "r");
137 if (!fp) {
138 ksft_perror(output);
140 return -1;
143 runs = 0;
144 while (fgets(temp, sizeof(temp), fp)) {
145 char *token = strtok(temp, ":\t");
146 int fields = 0;
148 while (token) {
149 token_array[fields++] = token;
150 token = strtok(NULL, ":\t");
153 /* Field 3 is perf imc value */
154 bw_imc[runs] = strtoul(token_array[3], NULL, 0);
155 /* Field 5 is resctrl value */
156 bw_resc[runs] = strtoul(token_array[5], NULL, 0);
157 runs++;
160 fclose(fp);
162 return show_mba_info(bw_imc, bw_resc);
165 static void mba_test_cleanup(void)
167 remove(RESULT_FILE_NAME);
170 static int mba_run_test(const struct resctrl_test *test, const struct user_params *uparams)
172 struct resctrl_val_param param = {
173 .ctrlgrp = "c1",
174 .filename = RESULT_FILE_NAME,
175 .init = mba_init,
176 .setup = mba_setup,
177 .measure = mba_measure,
179 struct fill_buf_param fill_buf = {};
180 int ret;
182 remove(RESULT_FILE_NAME);
184 if (uparams->fill_buf) {
185 fill_buf.buf_size = uparams->fill_buf->buf_size;
186 fill_buf.memflush = uparams->fill_buf->memflush;
187 param.fill_buf = &fill_buf;
188 } else if (!uparams->benchmark_cmd[0]) {
189 ssize_t buf_size;
191 buf_size = get_fill_buf_size(uparams->cpu, "L3");
192 if (buf_size < 0)
193 return buf_size;
194 fill_buf.buf_size = buf_size;
195 fill_buf.memflush = true;
196 param.fill_buf = &fill_buf;
199 ret = resctrl_val(test, uparams, &param);
200 if (ret)
201 return ret;
203 ret = check_results();
205 return ret;
208 static bool mba_feature_check(const struct resctrl_test *test)
210 return test_resource_feature_check(test) &&
211 resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes");
214 struct resctrl_test mba_test = {
215 .name = "MBA",
216 .resource = "MB",
217 .vendor_specific = ARCH_INTEL,
218 .feature_check = mba_feature_check,
219 .run_test = mba_run_test,
220 .cleanup = mba_test_cleanup,