Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/resctrl: Only support measured read operation

The CMT, MBM, and MBA tests rely on a benchmark to generate
memory traffic. By default this is the "fill_buf" benchmark that
can be replaced via the "-b" command line argument.

The original intent of the "-b" command line parameter was
to replace the default "fill_buf" benchmark, but the implementation
also exposes an alternative use case where the "fill_buf" parameters
itself can be modified. One of the parameters to "fill_buf" is the
"operation" that can be either "read" or "write" and indicates
whether the "fill_buf" should use "read" or "write" operations on the
allocated buffer.

While replacing "fill_buf" default parameters is technically possible,
replacing the default "read" parameter with "write" is not supported
because the MBA and MBM tests only measure "read" operations. The
"read" operation is also most appropriate for the CMT test that aims
to use the benchmark to allocate into the cache.

Avoid any potential inconsistencies between test and measurement by
removing code for unsupported "write" operations to the buffer.
Ignore any attempt from user space to enable this unsupported test
configuration, instead always use read operations.

Keep the initialization of the, now unused, "fill_buf" parameters
to reserve these parameter positions since it has been exposed as an API.
Future parameter additions cannot use these parameter positions.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Reinette Chatre and committed by
Shuah Khan
13842417 f3069136

+9 -31
+2 -26
tools/testing/selftests/resctrl/fill_buf.c
··· 88 88 return sum; 89 89 } 90 90 91 - static void fill_one_span_write(unsigned char *buf, size_t buf_size) 92 - { 93 - unsigned char *end_ptr = buf + buf_size; 94 - unsigned char *p; 95 - 96 - p = buf; 97 - while (p < end_ptr) { 98 - *p = '1'; 99 - p += (CL_SIZE / 2); 100 - } 101 - } 102 - 103 91 void fill_cache_read(unsigned char *buf, size_t buf_size, bool once) 104 92 { 105 93 int ret = 0; ··· 100 112 101 113 /* Consume read result so that reading memory is not optimized out. */ 102 114 *value_sink = ret; 103 - } 104 - 105 - static void fill_cache_write(unsigned char *buf, size_t buf_size, bool once) 106 - { 107 - while (1) { 108 - fill_one_span_write(buf, buf_size); 109 - if (once) 110 - break; 111 - } 112 115 } 113 116 114 117 unsigned char *alloc_buffer(size_t buf_size, int memflush) ··· 130 151 return buf; 131 152 } 132 153 133 - int run_fill_buf(size_t buf_size, int memflush, int op) 154 + int run_fill_buf(size_t buf_size, int memflush) 134 155 { 135 156 unsigned char *buf; 136 157 ··· 138 159 if (!buf) 139 160 return -1; 140 161 141 - if (op == 0) 142 - fill_cache_read(buf, buf_size, false); 143 - else 144 - fill_cache_write(buf, buf_size, false); 162 + fill_cache_read(buf, buf_size, false); 145 163 146 164 free(buf); 147 165
+1 -1
tools/testing/selftests/resctrl/resctrl.h
··· 142 142 unsigned char *alloc_buffer(size_t buf_size, int memflush); 143 143 void mem_flush(unsigned char *buf, size_t buf_size); 144 144 void fill_cache_read(unsigned char *buf, size_t buf_size, bool once); 145 - int run_fill_buf(size_t buf_size, int memflush, int op); 145 + int run_fill_buf(size_t buf_size, int memflush); 146 146 int initialize_mem_bw_imc(void); 147 147 int measure_mem_bw(const struct user_params *uparams, 148 148 struct resctrl_val_param *param, pid_t bm_pid,
+4 -1
tools/testing/selftests/resctrl/resctrl_tests.c
··· 265 265 ksft_exit_fail_msg("Out of memory!\n"); 266 266 uparams.benchmark_cmd[1] = span_str; 267 267 uparams.benchmark_cmd[2] = "1"; 268 - uparams.benchmark_cmd[3] = "0"; 269 268 /* 269 + * Third parameter was previously used for "operation" 270 + * (read/write) of which only (now default) "read"/"0" 271 + * works. 270 272 * Fourth parameter was previously used to indicate 271 273 * how long "fill_buf" should run for, with "false" 272 274 * ("fill_buf" will keep running until terminated) 273 275 * the only option that works. 274 276 */ 277 + uparams.benchmark_cmd[3] = NULL; 275 278 uparams.benchmark_cmd[4] = NULL; 276 279 } 277 280
+2 -3
tools/testing/selftests/resctrl/resctrl_val.c
··· 622 622 */ 623 623 static void run_benchmark(int signum, siginfo_t *info, void *ucontext) 624 624 { 625 - int operation, ret, memflush; 626 625 char **benchmark_cmd; 626 + int ret, memflush; 627 627 size_t span; 628 628 FILE *fp; 629 629 ··· 643 643 /* Execute default fill_buf benchmark */ 644 644 span = strtoul(benchmark_cmd[1], NULL, 10); 645 645 memflush = atoi(benchmark_cmd[2]); 646 - operation = atoi(benchmark_cmd[3]); 647 646 648 - if (run_fill_buf(span, memflush, operation)) 647 + if (run_fill_buf(span, memflush)) 649 648 fprintf(stderr, "Error in running fill buffer\n"); 650 649 } else { 651 650 /* Execute specified benchmark */