Skip to content

Commit 856385e

Browse files
committed
Merge tag 'linux_kselftest-next-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest update from Shuah Khan: "timer test: - remove duplicate defines - fixes to improve error reporting rtc test: - check rtc alarm status in alarm test resctrl test: - add array overrun checks during iMC config parsing code and when reading strings - fixes and reorganizing code" * tag 'linux_kselftest-next-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (23 commits) selftests/resctrl: Replace magic constants used as array size selftests/resctrl: Keep results from first test run selftests/resctrl: Do not compare performance counters and resctrl at low bandwidth selftests/resctrl: Use cache size to determine "fill_buf" buffer size selftests/resctrl: Ensure measurements skip initialization of default benchmark selftests/resctrl: Make benchmark parameter passing robust selftests/resctrl: Remove unused measurement code selftests/resctrl: Only support measured read operation selftests/resctrl: Remove "once" parameter required to be false selftests/resctrl: Make wraparound handling obvious selftests/resctrl: Protect against array overflow when reading strings selftests/resctrl: Protect against array overrun during iMC config parsing selftests/resctrl: Fix memory overflow due to unhandled wraparound selftests/resctrl: Print accurate buffer size as part of MBM results selftests/resctrl: Make functions only used in same file static selftests: Add a test mangling with uc_sigmask selftests: Rename sigaltstack to generic signal selftest: rtc: Add to check rtc alarm status for alarm related test selftests:timers: remove local CLOCKID defines selftests: timers: Remove unneeded semicolon ...
2 parents f89a687 + a44c26d commit 856385e

31 files changed

+701
-569
lines changed

Documentation/dev-tools/kselftest.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ kselftest runs as a userspace process. Tests that can be written/run in
3131
userspace may wish to use the `Test Harness`_. Tests that need to be
3232
run in kernel space may wish to use a `Test Module`_.
3333

34+
Documentation on the tests
35+
==========================
36+
37+
For documentation on the kselftests themselves, see:
38+
39+
.. toctree::
40+
41+
testing-devices
42+
3443
Running the selftests (hotplug tests are run in limited mode)
3544
=============================================================
3645

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
.. Copyright (c) 2024 Collabora Ltd
3+
4+
=============================
5+
Device testing with kselftest
6+
=============================
7+
8+
9+
There are a few different kselftests available for testing devices generically,
10+
with some overlap in coverage and different requirements. This document aims to
11+
give an overview of each one.
12+
13+
Note: Paths in this document are relative to the kselftest folder
14+
(``tools/testing/selftests``).
15+
16+
Device oriented kselftests:
17+
18+
* Devicetree (``dt``)
19+
20+
* **Coverage**: Probe status for devices described in Devicetree
21+
* **Requirements**: None
22+
23+
* Error logs (``devices/error_logs``)
24+
25+
* **Coverage**: Error (or more critical) log messages presence coming from any
26+
device
27+
* **Requirements**: None
28+
29+
* Discoverable bus (``devices/probe``)
30+
31+
* **Coverage**: Presence and probe status of USB or PCI devices that have been
32+
described in the reference file
33+
* **Requirements**: Manually describe the devices that should be tested in a
34+
YAML reference file (see ``devices/probe/boards/google,spherion.yaml`` for
35+
an example)
36+
37+
* Exist (``devices/exist``)
38+
39+
* **Coverage**: Presence of all devices
40+
* **Requirements**: Generate the reference (see ``devices/exist/README.rst``
41+
for details) on a known-good kernel
42+
43+
Therefore, the suggestion is to enable the error log and devicetree tests on all
44+
(DT-based) platforms, since they don't have any requirements. Then to greatly
45+
improve coverage, generate the reference for each platform and enable the exist
46+
test. The discoverable bus test can be used to verify the probe status of
47+
specific USB or PCI devices, but is probably not worth it for most cases.

tools/testing/selftests/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ TARGETS += rust
9191
TARGETS += sched_ext
9292
TARGETS += seccomp
9393
TARGETS += sgx
94-
TARGETS += sigaltstack
94+
TARGETS += signal
9595
TARGETS += size
9696
TARGETS += sparc64
9797
TARGETS += splice

tools/testing/selftests/resctrl/cmt_test.c

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,13 @@ static int check_results(struct resctrl_val_param *param, size_t span, int no_of
9999
}
100100

101101
/* Field 3 is llc occ resc value */
102-
if (runs > 0)
103-
sum_llc_occu_resc += strtoul(token_array[3], NULL, 0);
102+
sum_llc_occu_resc += strtoul(token_array[3], NULL, 0);
104103
runs++;
105104
}
106105
fclose(fp);
107106

108107
return show_results_info(sum_llc_occu_resc, no_of_bits, span,
109-
MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, true);
108+
MAX_DIFF, MAX_DIFF_PERCENT, runs, true);
110109
}
111110

112111
static void cmt_test_cleanup(void)
@@ -116,15 +115,13 @@ static void cmt_test_cleanup(void)
116115

117116
static int cmt_run_test(const struct resctrl_test *test, const struct user_params *uparams)
118117
{
119-
const char * const *cmd = uparams->benchmark_cmd;
120-
const char *new_cmd[BENCHMARK_ARGS];
118+
struct fill_buf_param fill_buf = {};
121119
unsigned long cache_total_size = 0;
122120
int n = uparams->bits ? : 5;
123121
unsigned long long_mask;
124-
char *span_str = NULL;
125122
int count_of_bits;
126123
size_t span;
127-
int ret, i;
124+
int ret;
128125

129126
ret = get_full_cbm("L3", &long_mask);
130127
if (ret)
@@ -155,32 +152,26 @@ static int cmt_run_test(const struct resctrl_test *test, const struct user_param
155152

156153
span = cache_portion_size(cache_total_size, param.mask, long_mask);
157154

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;
155+
if (uparams->fill_buf) {
156+
fill_buf.buf_size = span;
157+
fill_buf.memflush = uparams->fill_buf->memflush;
158+
param.fill_buf = &fill_buf;
159+
} else if (!uparams->benchmark_cmd[0]) {
160+
fill_buf.buf_size = span;
161+
fill_buf.memflush = true;
162+
param.fill_buf = &fill_buf;
169163
}
170164

171165
remove(RESULT_FILE_NAME);
172166

173-
ret = resctrl_val(test, uparams, cmd, &param);
167+
ret = resctrl_val(test, uparams, &param);
174168
if (ret)
175-
goto out;
169+
return ret;
176170

177171
ret = check_results(&param, span, n);
178172
if (ret && (get_vendor() == ARCH_INTEL))
179173
ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
180174

181-
out:
182-
free(span_str);
183-
184175
return ret;
185176
}
186177

tools/testing/selftests/resctrl/fill_buf.c

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,6 @@ static int fill_one_span_read(unsigned char *buf, size_t buf_size)
8888
return sum;
8989
}
9090

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-
10391
void fill_cache_read(unsigned char *buf, size_t buf_size, bool once)
10492
{
10593
int ret = 0;
@@ -114,20 +102,11 @@ void fill_cache_read(unsigned char *buf, size_t buf_size, bool once)
114102
*value_sink = ret;
115103
}
116104

117-
static void fill_cache_write(unsigned char *buf, size_t buf_size, bool once)
118-
{
119-
while (1) {
120-
fill_one_span_write(buf, buf_size);
121-
if (once)
122-
break;
123-
}
124-
}
125-
126-
unsigned char *alloc_buffer(size_t buf_size, int memflush)
105+
unsigned char *alloc_buffer(size_t buf_size, bool memflush)
127106
{
128107
void *buf = NULL;
129108
uint64_t *p64;
130-
size_t s64;
109+
ssize_t s64;
131110
int ret;
132111

133112
ret = posix_memalign(&buf, PAGE_SIZE, buf_size);
@@ -151,19 +130,15 @@ unsigned char *alloc_buffer(size_t buf_size, int memflush)
151130
return buf;
152131
}
153132

154-
int run_fill_buf(size_t buf_size, int memflush, int op, bool once)
133+
ssize_t get_fill_buf_size(int cpu_no, const char *cache_type)
155134
{
156-
unsigned char *buf;
157-
158-
buf = alloc_buffer(buf_size, memflush);
159-
if (!buf)
160-
return -1;
135+
unsigned long cache_total_size = 0;
136+
int ret;
161137

162-
if (op == 0)
163-
fill_cache_read(buf, buf_size, once);
164-
else
165-
fill_cache_write(buf, buf_size, once);
166-
free(buf);
138+
ret = get_cache_size(cpu_no, cache_type, &cache_total_size);
139+
if (ret)
140+
return ret;
167141

168-
return 0;
142+
return cache_total_size * 2 > MINIMUM_SPAN ?
143+
cache_total_size * 2 : MINIMUM_SPAN;
169144
}

tools/testing/selftests/resctrl/mba_test.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static int mba_init(const struct resctrl_val_param *param, int domain_id)
2121
{
2222
int ret;
2323

24-
ret = initialize_mem_bw_imc();
24+
ret = initialize_read_mem_bw_imc();
2525
if (ret)
2626
return ret;
2727

@@ -39,7 +39,8 @@ static int mba_setup(const struct resctrl_test *test,
3939
const struct user_params *uparams,
4040
struct resctrl_val_param *p)
4141
{
42-
static int runs_per_allocation, allocation = 100;
42+
static unsigned int allocation = ALLOCATION_MIN;
43+
static int runs_per_allocation;
4344
char allocation_str[64];
4445
int ret;
4546

@@ -50,7 +51,7 @@ static int mba_setup(const struct resctrl_test *test,
5051
if (runs_per_allocation++ != 0)
5152
return 0;
5253

53-
if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX)
54+
if (allocation > ALLOCATION_MAX)
5455
return END_OF_TESTS;
5556

5657
sprintf(allocation_str, "%d", allocation);
@@ -59,21 +60,22 @@ static int mba_setup(const struct resctrl_test *test,
5960
if (ret < 0)
6061
return ret;
6162

62-
allocation -= ALLOCATION_STEP;
63+
allocation += ALLOCATION_STEP;
6364

6465
return 0;
6566
}
6667

6768
static int mba_measure(const struct user_params *uparams,
6869
struct resctrl_val_param *param, pid_t bm_pid)
6970
{
70-
return measure_mem_bw(uparams, param, bm_pid, "reads");
71+
return measure_read_mem_bw(uparams, param, bm_pid);
7172
}
7273

7374
static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
7475
{
75-
int allocation, runs;
76+
unsigned int allocation;
7677
bool ret = false;
78+
int runs;
7779

7880
ksft_print_msg("Results are displayed in (MB)\n");
7981
/* Memory bandwidth from 100% down to 10% */
@@ -84,26 +86,29 @@ static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
8486
int avg_diff_per;
8587
float avg_diff;
8688

87-
/*
88-
* The first run is discarded due to inaccurate value from
89-
* phase transition.
90-
*/
91-
for (runs = NUM_OF_RUNS * allocation + 1;
89+
for (runs = NUM_OF_RUNS * allocation;
9290
runs < NUM_OF_RUNS * allocation + NUM_OF_RUNS ; runs++) {
9391
sum_bw_imc += bw_imc[runs];
9492
sum_bw_resc += bw_resc[runs];
9593
}
9694

97-
avg_bw_imc = sum_bw_imc / (NUM_OF_RUNS - 1);
98-
avg_bw_resc = sum_bw_resc / (NUM_OF_RUNS - 1);
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;
102+
}
103+
99104
avg_diff = (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc;
100105
avg_diff_per = (int)(avg_diff * 100);
101106

102107
ksft_print_msg("%s Check MBA diff within %d%% for schemata %u\n",
103108
avg_diff_per > MAX_DIFF_PERCENT ?
104109
"Fail:" : "Pass:",
105110
MAX_DIFF_PERCENT,
106-
ALLOCATION_MAX - ALLOCATION_STEP * allocation);
111+
ALLOCATION_MIN + ALLOCATION_STEP * allocation);
107112

108113
ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per);
109114
ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc);
@@ -122,8 +127,9 @@ static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
122127

123128
static int check_results(void)
124129
{
130+
unsigned long bw_resc[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP];
131+
unsigned long bw_imc[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP];
125132
char *token_array[8], output[] = RESULT_FILE_NAME, temp[512];
126-
unsigned long bw_imc[1024], bw_resc[1024];
127133
int runs;
128134
FILE *fp;
129135

@@ -170,11 +176,27 @@ static int mba_run_test(const struct resctrl_test *test, const struct user_param
170176
.setup = mba_setup,
171177
.measure = mba_measure,
172178
};
179+
struct fill_buf_param fill_buf = {};
173180
int ret;
174181

175182
remove(RESULT_FILE_NAME);
176183

177-
ret = resctrl_val(test, uparams, uparams->benchmark_cmd, &param);
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;
190+
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;
197+
}
198+
199+
ret = resctrl_val(test, uparams, &param);
178200
if (ret)
179201
return ret;
180202

0 commit comments

Comments
 (0)