Skip to content

Commit e33cb57

Browse files
ij-intelshuahkh
authored andcommitted
selftests/resctrl: Make benchmark command const and build it with pointers
Benchmark command is used in multiple tests so it should not be mutated by the tests but CMT test alters span argument. Due to the order of tests (CMT test runs last), mutating the span argument in CMT test does not trigger any real problems currently. Mark benchmark_cmd strings as const and setup the benchmark command using pointers. Because the benchmark command becomes const, the input arguments can be used directly. Besides being simpler, using the input arguments directly also removes the internal size restriction. CMT test has to create a copy of the benchmark command before altering the benchmark command. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent 47809eb commit e33cb57

6 files changed

Lines changed: 53 additions & 35 deletions

File tree

tools/testing/selftests/resctrl/cmt_test.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,17 @@ void cmt_test_cleanup(void)
6868
remove(RESULT_FILE_NAME);
6969
}
7070

71-
int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
71+
int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd)
7272
{
73+
const char * const *cmd = benchmark_cmd;
74+
const char *new_cmd[BENCHMARK_ARGS];
7375
unsigned long cache_size = 0;
7476
unsigned long long_mask;
77+
char *span_str = NULL;
7578
char cbm_mask[256];
7679
int count_of_bits;
7780
size_t span;
78-
int ret;
81+
int ret, i;
7982

8083
if (!validate_resctrl_feature_request(CMT_STR))
8184
return -1;
@@ -111,19 +114,31 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
111114
};
112115

113116
span = cache_size * n / count_of_bits;
114-
if (strcmp(benchmark_cmd[0], "fill_buf") == 0)
115-
sprintf(benchmark_cmd[1], "%zu", span);
117+
118+
if (strcmp(cmd[0], "fill_buf") == 0) {
119+
/* Duplicate the command to be able to replace span in it */
120+
for (i = 0; benchmark_cmd[i]; i++)
121+
new_cmd[i] = benchmark_cmd[i];
122+
new_cmd[i] = NULL;
123+
124+
ret = asprintf(&span_str, "%zu", span);
125+
if (ret < 0)
126+
return -1;
127+
new_cmd[1] = span_str;
128+
cmd = new_cmd;
129+
}
116130

117131
remove(RESULT_FILE_NAME);
118132

119-
ret = resctrl_val(benchmark_cmd, &param);
133+
ret = resctrl_val(cmd, &param);
120134
if (ret)
121135
goto out;
122136

123137
ret = check_results(&param, span, n);
124138

125139
out:
126140
cmt_test_cleanup();
141+
free(span_str);
127142

128143
return ret;
129144
}

tools/testing/selftests/resctrl/mba_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void mba_test_cleanup(void)
141141
remove(RESULT_FILE_NAME);
142142
}
143143

144-
int mba_schemata_change(int cpu_no, char **benchmark_cmd)
144+
int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd)
145145
{
146146
struct resctrl_val_param param = {
147147
.resctrl_val = MBA_STR,

tools/testing/selftests/resctrl/mbm_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void mbm_test_cleanup(void)
109109
remove(RESULT_FILE_NAME);
110110
}
111111

112-
int mbm_bw_change(int cpu_no, char **benchmark_cmd)
112+
int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd)
113113
{
114114
struct resctrl_val_param param = {
115115
.resctrl_val = MBM_STR,

tools/testing/selftests/resctrl/resctrl.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
#define END_OF_TESTS 1
4040

41+
#define BENCHMARK_ARGS 64
42+
4143
#define DEFAULT_SPAN (250 * MB)
4244

4345
#define PARENT_EXIT(err_msg) \
@@ -97,11 +99,11 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
9799
int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
98100
int group_fd, unsigned long flags);
99101
int run_fill_buf(size_t span, int memflush, int op, bool once);
100-
int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param);
101-
int mbm_bw_change(int cpu_no, char **benchmark_cmd);
102+
int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param);
103+
int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd);
102104
void tests_cleanup(void);
103105
void mbm_test_cleanup(void);
104-
int mba_schemata_change(int cpu_no, char **benchmark_cmd);
106+
int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd);
105107
void mba_test_cleanup(void);
106108
int get_cbm_mask(char *cache_type, char *cbm_mask);
107109
int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
@@ -111,7 +113,7 @@ void signal_handler_unregister(void);
111113
int cat_val(struct resctrl_val_param *param, size_t span);
112114
void cat_test_cleanup(void);
113115
int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
114-
int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd);
116+
int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd);
115117
unsigned int count_bits(unsigned long n);
116118
void cmt_test_cleanup(void);
117119
int get_core_sibling(int cpu_no);

tools/testing/selftests/resctrl/resctrl_tests.c

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
*/
1111
#include "resctrl.h"
1212

13-
#define BENCHMARK_ARGS 64
14-
#define BENCHMARK_ARG_SIZE 64
15-
1613
static int detect_vendor(void)
1714
{
1815
FILE *inf = fopen("/proc/cpuinfo", "r");
@@ -70,7 +67,7 @@ void tests_cleanup(void)
7067
cat_test_cleanup();
7168
}
7269

73-
static void run_mbm_test(char **benchmark_cmd, int cpu_no)
70+
static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
7471
{
7572
int res;
7673

@@ -96,7 +93,7 @@ static void run_mbm_test(char **benchmark_cmd, int cpu_no)
9693
umount_resctrlfs();
9794
}
9895

99-
static void run_mba_test(char **benchmark_cmd, int cpu_no)
96+
static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
10097
{
10198
int res;
10299

@@ -120,7 +117,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no)
120117
umount_resctrlfs();
121118
}
122119

123-
static void run_cmt_test(char **benchmark_cmd, int cpu_no)
120+
static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
124121
{
125122
int res;
126123

@@ -173,11 +170,12 @@ static void run_cat_test(int cpu_no, int no_of_bits)
173170
int main(int argc, char **argv)
174171
{
175172
bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true;
176-
char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE];
177173
int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0;
178-
char *benchmark_cmd[BENCHMARK_ARGS];
174+
const char *benchmark_cmd[BENCHMARK_ARGS];
179175
int ben_ind, ben_count, tests = 0;
176+
char *span_str = NULL;
180177
bool cat_test = true;
178+
int ret;
181179

182180
for (i = 0; i < argc; i++) {
183181
if (strcmp(argv[i], "-b") == 0) {
@@ -265,23 +263,19 @@ int main(int argc, char **argv)
265263
ksft_exit_fail_msg("Too long benchmark command.\n");
266264

267265
/* Extract benchmark command from command line. */
268-
for (i = ben_ind; i < argc; i++) {
269-
benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i];
270-
if (strlen(argv[i]) >= BENCHMARK_ARG_SIZE)
271-
ksft_exit_fail_msg("Too long benchmark command argument.\n");
272-
sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]);
273-
}
266+
for (i = 0; i < argc - ben_ind; i++)
267+
benchmark_cmd[i] = argv[i + ben_ind];
274268
benchmark_cmd[ben_count] = NULL;
275269
} else {
276270
/* If no benchmark is given by "-b" argument, use fill_buf. */
277-
for (i = 0; i < 5; i++)
278-
benchmark_cmd[i] = benchmark_cmd_area[i];
279-
280-
strcpy(benchmark_cmd[0], "fill_buf");
281-
sprintf(benchmark_cmd[1], "%u", DEFAULT_SPAN);
282-
strcpy(benchmark_cmd[2], "1");
283-
strcpy(benchmark_cmd[3], "0");
284-
strcpy(benchmark_cmd[4], "false");
271+
benchmark_cmd[0] = "fill_buf";
272+
ret = asprintf(&span_str, "%u", DEFAULT_SPAN);
273+
if (ret < 0)
274+
ksft_exit_fail_msg("Out of memory!\n");
275+
benchmark_cmd[1] = span_str;
276+
benchmark_cmd[2] = "1";
277+
benchmark_cmd[3] = "0";
278+
benchmark_cmd[4] = "false";
285279
benchmark_cmd[5] = NULL;
286280
}
287281

@@ -299,5 +293,6 @@ int main(int argc, char **argv)
299293
if (cat_test)
300294
run_cat_test(cpu_no, no_of_bits);
301295

296+
free(span_str);
302297
ksft_finished();
303298
}

tools/testing/selftests/resctrl/resctrl_val.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
629629
*
630630
* Return: 0 on success. non-zero on failure.
631631
*/
632-
int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
632+
int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param)
633633
{
634634
char *resctrl_val = param->resctrl_val;
635635
unsigned long bw_resc_start = 0;
@@ -710,7 +710,13 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
710710
if (ret)
711711
goto out;
712712

713-
value.sival_ptr = benchmark_cmd;
713+
/*
714+
* The cast removes constness but nothing mutates benchmark_cmd within
715+
* the context of this process. At the receiving process, it becomes
716+
* argv, which is mutable, on exec() but that's after fork() so it
717+
* doesn't matter for the process running the tests.
718+
*/
719+
value.sival_ptr = (void *)benchmark_cmd;
714720

715721
/* Taskset benchmark to specified cpu */
716722
ret = taskset_benchmark(bm_pid, param->cpu_no);

0 commit comments

Comments
 (0)