diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-06 16:11:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-06 16:11:51 -0400 |
commit | ca95bf62fcf528a0d8069731d39303ba43fb9af4 (patch) | |
tree | e5d746396a7aa08efecd69bf8917c23810797efe | |
parent | 0ad39cb3d70fb4324d127aeceee7f63e3f71605c (diff) | |
parent | fa32156921daa5c175228e2cac7679d50efd6c52 (diff) |
Merge tag 'linux-kselftest-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull Kselftest update from Shuah Khan:
- Work to restructure timers test suite to move PIE out of rtctest from
Alexandre Belloni.
- Several minor spelling and bug fixes.
- New cgroup tests from Roman Gushchin and Mike Rapoport.
- Kselftest framework changes to handle and report skipped tests
correctly.
Prior to these changes, framework treated all non-zero return codes
from tests as failures. When tests are skipped with non-zero return
code, due to unmet dependencies and/or unsupported configuration,
reporting them as failed lead to false negatives on the tests that
couldn't be run.
- Fixes to test Makefiles to remove unnecessary RUN_TESTS and
EMIT_TESTS overrides and use common defines from lib.mk.
- Fixes to several tests to return correct Kselftest skip code.
- Changes to improve test output.
* tag 'linux-kselftest-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (55 commits)
selftests: lib: fix prime_numbers module search and skip logic
selftests: intel_pstate: notification about privilege required to run intel_pstate testing script
selftests: cgroup/memcontrol: add basic test for socket accounting
selftest: intel_pstate: debug support message from aperf.c and return value
kselftest/cgroup: fix variable dereferenced before check warning
selftests/intel_pstate: Enhance table printing
selftests/intel_pstate: Improve test, minor fixes
selftests: cgroup/memcontrol: add basic test for swap controls
selftests: cgroup: add memory controller self-tests
selftests: memfd: split regular and hugetlbfs tests
selftests: net: return Kselftest Skip code for skipped tests
selftests: mqueue: return Kselftest Skip code for skipped tests
selftests: memory-hotplug: return Kselftest Skip code for skipped tests
selftests: memfd: return Kselftest Skip code for skipped tests
selftests: membarrier: return Kselftest Skip code for skipped tests
selftests: media_tests: return Kselftest Skip code for skipped tests
selftests: locking: return Kselftest Skip code for skipped tests
selftests: locking: add Makefile for locking test
selftests: lib: return Kselftest Skip code for skipped tests
selftests: lib: add prime_numbers.sh test to Makefile
...
63 files changed, 2113 insertions, 615 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 66cd131c517d..f446443a556e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11935,7 +11935,7 @@ F: include/linux/rtc.h | |||
11935 | F: include/uapi/linux/rtc.h | 11935 | F: include/uapi/linux/rtc.h |
11936 | F: include/linux/rtc/ | 11936 | F: include/linux/rtc/ |
11937 | F: include/linux/platform_data/rtc-* | 11937 | F: include/linux/platform_data/rtc-* |
11938 | F: tools/testing/selftests/timers/rtctest.c | 11938 | F: tools/testing/selftests/rtc/ |
11939 | 11939 | ||
11940 | REALTEK AUDIO CODECS | 11940 | REALTEK AUDIO CODECS |
11941 | M: Bard Liao <bardliao@realtek.com> | 11941 | M: Bard Liao <bardliao@realtek.com> |
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 32aafa92074c..305130de910c 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile | |||
@@ -3,6 +3,7 @@ TARGETS = android | |||
3 | TARGETS += bpf | 3 | TARGETS += bpf |
4 | TARGETS += breakpoints | 4 | TARGETS += breakpoints |
5 | TARGETS += capabilities | 5 | TARGETS += capabilities |
6 | TARGETS += cgroup | ||
6 | TARGETS += cpufreq | 7 | TARGETS += cpufreq |
7 | TARGETS += cpu-hotplug | 8 | TARGETS += cpu-hotplug |
8 | TARGETS += efivarfs | 9 | TARGETS += efivarfs |
@@ -28,6 +29,7 @@ TARGETS += powerpc | |||
28 | TARGETS += proc | 29 | TARGETS += proc |
29 | TARGETS += pstore | 30 | TARGETS += pstore |
30 | TARGETS += ptrace | 31 | TARGETS += ptrace |
32 | TARGETS += rtc | ||
31 | TARGETS += seccomp | 33 | TARGETS += seccomp |
32 | TARGETS += sigaltstack | 34 | TARGETS += sigaltstack |
33 | TARGETS += size | 35 | TARGETS += size |
@@ -134,7 +136,8 @@ ifdef INSTALL_PATH | |||
134 | echo "else" >> $(ALL_SCRIPT) | 136 | echo "else" >> $(ALL_SCRIPT) |
135 | echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT) | 137 | echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT) |
136 | echo "fi" >> $(ALL_SCRIPT) | 138 | echo "fi" >> $(ALL_SCRIPT) |
137 | echo "export KSFT_TAP_LEVEL=`echo 1`" >> $(ALL_SCRIPT) | 139 | echo "export KSFT_TAP_LEVEL=1" >> $(ALL_SCRIPT) |
140 | echo "export skip=4" >> $(ALL_SCRIPT) | ||
138 | 141 | ||
139 | for TARGET in $(TARGETS); do \ | 142 | for TARGET in $(TARGETS); do \ |
140 | BUILD_TARGET=$$BUILD/$$TARGET; \ | 143 | BUILD_TARGET=$$BUILD/$$TARGET; \ |
diff --git a/tools/testing/selftests/android/Makefile b/tools/testing/selftests/android/Makefile index f6304d2be90c..72c25a3cb658 100644 --- a/tools/testing/selftests/android/Makefile +++ b/tools/testing/selftests/android/Makefile | |||
@@ -18,10 +18,6 @@ all: | |||
18 | fi \ | 18 | fi \ |
19 | done | 19 | done |
20 | 20 | ||
21 | override define RUN_TESTS | ||
22 | @cd $(OUTPUT); ./run.sh | ||
23 | endef | ||
24 | |||
25 | override define INSTALL_RULE | 21 | override define INSTALL_RULE |
26 | mkdir -p $(INSTALL_PATH) | 22 | mkdir -p $(INSTALL_PATH) |
27 | install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) | 23 | install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) |
@@ -33,10 +29,6 @@ override define INSTALL_RULE | |||
33 | done; | 29 | done; |
34 | endef | 30 | endef |
35 | 31 | ||
36 | override define EMIT_TESTS | ||
37 | echo "./run.sh" | ||
38 | endef | ||
39 | |||
40 | override define CLEAN | 32 | override define CLEAN |
41 | @for DIR in $(SUBDIRS); do \ | 33 | @for DIR in $(SUBDIRS); do \ |
42 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ | 34 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ |
diff --git a/tools/testing/selftests/android/ion/ion_test.sh b/tools/testing/selftests/android/ion/ion_test.sh index a1aff506f5e6..69e676cfc94e 100755 --- a/tools/testing/selftests/android/ion/ion_test.sh +++ b/tools/testing/selftests/android/ion/ion_test.sh | |||
@@ -4,6 +4,9 @@ heapsize=4096 | |||
4 | TCID="ion_test.sh" | 4 | TCID="ion_test.sh" |
5 | errcode=0 | 5 | errcode=0 |
6 | 6 | ||
7 | # Kselftest framework requirement - SKIP code is 4. | ||
8 | ksft_skip=4 | ||
9 | |||
7 | run_test() | 10 | run_test() |
8 | { | 11 | { |
9 | heaptype=$1 | 12 | heaptype=$1 |
@@ -25,7 +28,7 @@ check_root() | |||
25 | uid=$(id -u) | 28 | uid=$(id -u) |
26 | if [ $uid -ne 0 ]; then | 29 | if [ $uid -ne 0 ]; then |
27 | echo $TCID: must be run as root >&2 | 30 | echo $TCID: must be run as root >&2 |
28 | exit 0 | 31 | exit $ksft_skip |
29 | fi | 32 | fi |
30 | } | 33 | } |
31 | 34 | ||
@@ -35,7 +38,7 @@ check_device() | |||
35 | if [ ! -e $DEVICE ]; then | 38 | if [ ! -e $DEVICE ]; then |
36 | echo $TCID: No $DEVICE device found >&2 | 39 | echo $TCID: No $DEVICE device found >&2 |
37 | echo $TCID: May be CONFIG_ION is not set >&2 | 40 | echo $TCID: May be CONFIG_ION is not set >&2 |
38 | exit 0 | 41 | exit $ksft_skip |
39 | fi | 42 | fi |
40 | } | 43 | } |
41 | 44 | ||
diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c index 3fece06e9f64..f82dcc1f8841 100644 --- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c +++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c | |||
@@ -143,10 +143,14 @@ void suspend(void) | |||
143 | int err; | 143 | int err; |
144 | struct itimerspec spec = {}; | 144 | struct itimerspec spec = {}; |
145 | 145 | ||
146 | if (getuid() != 0) | ||
147 | ksft_exit_skip("Please run the test as root - Exiting.\n"); | ||
148 | |||
146 | power_state_fd = open("/sys/power/state", O_RDWR); | 149 | power_state_fd = open("/sys/power/state", O_RDWR); |
147 | if (power_state_fd < 0) | 150 | if (power_state_fd < 0) |
148 | ksft_exit_fail_msg( | 151 | ksft_exit_fail_msg( |
149 | "open(\"/sys/power/state\") failed (is this test running as root?)\n"); | 152 | "open(\"/sys/power/state\") failed %s)\n", |
153 | strerror(errno)); | ||
150 | 154 | ||
151 | timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); | 155 | timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); |
152 | if (timerfd < 0) | 156 | if (timerfd < 0) |
diff --git a/tools/testing/selftests/cgroup/Makefile b/tools/testing/selftests/cgroup/Makefile new file mode 100644 index 000000000000..f7a31392eb2f --- /dev/null +++ b/tools/testing/selftests/cgroup/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | CFLAGS += -Wall | ||
3 | |||
4 | all: | ||
5 | |||
6 | TEST_GEN_PROGS = test_memcontrol | ||
7 | |||
8 | include ../lib.mk | ||
9 | |||
10 | $(OUTPUT)/test_memcontrol: cgroup_util.c | ||
diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c new file mode 100644 index 000000000000..b69bdeb4b9fe --- /dev/null +++ b/tools/testing/selftests/cgroup/cgroup_util.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #define _GNU_SOURCE | ||
4 | |||
5 | #include <errno.h> | ||
6 | #include <fcntl.h> | ||
7 | #include <linux/limits.h> | ||
8 | #include <signal.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <sys/types.h> | ||
14 | #include <sys/wait.h> | ||
15 | #include <unistd.h> | ||
16 | |||
17 | #include "cgroup_util.h" | ||
18 | |||
19 | static ssize_t read_text(const char *path, char *buf, size_t max_len) | ||
20 | { | ||
21 | ssize_t len; | ||
22 | int fd; | ||
23 | |||
24 | fd = open(path, O_RDONLY); | ||
25 | if (fd < 0) | ||
26 | return fd; | ||
27 | |||
28 | len = read(fd, buf, max_len - 1); | ||
29 | if (len < 0) | ||
30 | goto out; | ||
31 | |||
32 | buf[len] = 0; | ||
33 | out: | ||
34 | close(fd); | ||
35 | return len; | ||
36 | } | ||
37 | |||
38 | static ssize_t write_text(const char *path, char *buf, size_t len) | ||
39 | { | ||
40 | int fd; | ||
41 | |||
42 | fd = open(path, O_WRONLY | O_APPEND); | ||
43 | if (fd < 0) | ||
44 | return fd; | ||
45 | |||
46 | len = write(fd, buf, len); | ||
47 | if (len < 0) { | ||
48 | close(fd); | ||
49 | return len; | ||
50 | } | ||
51 | |||
52 | close(fd); | ||
53 | |||
54 | return len; | ||
55 | } | ||
56 | |||
57 | char *cg_name(const char *root, const char *name) | ||
58 | { | ||
59 | size_t len = strlen(root) + strlen(name) + 2; | ||
60 | char *ret = malloc(len); | ||
61 | |||
62 | snprintf(ret, len, "%s/%s", root, name); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | char *cg_name_indexed(const char *root, const char *name, int index) | ||
68 | { | ||
69 | size_t len = strlen(root) + strlen(name) + 10; | ||
70 | char *ret = malloc(len); | ||
71 | |||
72 | snprintf(ret, len, "%s/%s_%d", root, name, index); | ||
73 | |||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | int cg_read(const char *cgroup, const char *control, char *buf, size_t len) | ||
78 | { | ||
79 | char path[PATH_MAX]; | ||
80 | |||
81 | snprintf(path, sizeof(path), "%s/%s", cgroup, control); | ||
82 | |||
83 | if (read_text(path, buf, len) >= 0) | ||
84 | return 0; | ||
85 | |||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | int cg_read_strcmp(const char *cgroup, const char *control, | ||
90 | const char *expected) | ||
91 | { | ||
92 | size_t size = strlen(expected) + 1; | ||
93 | char *buf; | ||
94 | |||
95 | buf = malloc(size); | ||
96 | if (!buf) | ||
97 | return -1; | ||
98 | |||
99 | if (cg_read(cgroup, control, buf, size)) | ||
100 | return -1; | ||
101 | |||
102 | return strcmp(expected, buf); | ||
103 | } | ||
104 | |||
105 | int cg_read_strstr(const char *cgroup, const char *control, const char *needle) | ||
106 | { | ||
107 | char buf[PAGE_SIZE]; | ||
108 | |||
109 | if (cg_read(cgroup, control, buf, sizeof(buf))) | ||
110 | return -1; | ||
111 | |||
112 | return strstr(buf, needle) ? 0 : -1; | ||
113 | } | ||
114 | |||
115 | long cg_read_long(const char *cgroup, const char *control) | ||
116 | { | ||
117 | char buf[128]; | ||
118 | |||
119 | if (cg_read(cgroup, control, buf, sizeof(buf))) | ||
120 | return -1; | ||
121 | |||
122 | return atol(buf); | ||
123 | } | ||
124 | |||
125 | long cg_read_key_long(const char *cgroup, const char *control, const char *key) | ||
126 | { | ||
127 | char buf[PAGE_SIZE]; | ||
128 | char *ptr; | ||
129 | |||
130 | if (cg_read(cgroup, control, buf, sizeof(buf))) | ||
131 | return -1; | ||
132 | |||
133 | ptr = strstr(buf, key); | ||
134 | if (!ptr) | ||
135 | return -1; | ||
136 | |||
137 | return atol(ptr + strlen(key)); | ||
138 | } | ||
139 | |||
140 | int cg_write(const char *cgroup, const char *control, char *buf) | ||
141 | { | ||
142 | char path[PATH_MAX]; | ||
143 | size_t len = strlen(buf); | ||
144 | |||
145 | snprintf(path, sizeof(path), "%s/%s", cgroup, control); | ||
146 | |||
147 | if (write_text(path, buf, len) == len) | ||
148 | return 0; | ||
149 | |||
150 | return -1; | ||
151 | } | ||
152 | |||
153 | int cg_find_unified_root(char *root, size_t len) | ||
154 | { | ||
155 | char buf[10 * PAGE_SIZE]; | ||
156 | char *fs, *mount, *type; | ||
157 | const char delim[] = "\n\t "; | ||
158 | |||
159 | if (read_text("/proc/self/mounts", buf, sizeof(buf)) <= 0) | ||
160 | return -1; | ||
161 | |||
162 | /* | ||
163 | * Example: | ||
164 | * cgroup /sys/fs/cgroup cgroup2 rw,seclabel,noexec,relatime 0 0 | ||
165 | */ | ||
166 | for (fs = strtok(buf, delim); fs; fs = strtok(NULL, delim)) { | ||
167 | mount = strtok(NULL, delim); | ||
168 | type = strtok(NULL, delim); | ||
169 | strtok(NULL, delim); | ||
170 | strtok(NULL, delim); | ||
171 | strtok(NULL, delim); | ||
172 | |||
173 | if (strcmp(fs, "cgroup") == 0 && | ||
174 | strcmp(type, "cgroup2") == 0) { | ||
175 | strncpy(root, mount, len); | ||
176 | return 0; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | return -1; | ||
181 | } | ||
182 | |||
183 | int cg_create(const char *cgroup) | ||
184 | { | ||
185 | return mkdir(cgroup, 0644); | ||
186 | } | ||
187 | |||
188 | static int cg_killall(const char *cgroup) | ||
189 | { | ||
190 | char buf[PAGE_SIZE]; | ||
191 | char *ptr = buf; | ||
192 | |||
193 | if (cg_read(cgroup, "cgroup.procs", buf, sizeof(buf))) | ||
194 | return -1; | ||
195 | |||
196 | while (ptr < buf + sizeof(buf)) { | ||
197 | int pid = strtol(ptr, &ptr, 10); | ||
198 | |||
199 | if (pid == 0) | ||
200 | break; | ||
201 | if (*ptr) | ||
202 | ptr++; | ||
203 | else | ||
204 | break; | ||
205 | if (kill(pid, SIGKILL)) | ||
206 | return -1; | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | int cg_destroy(const char *cgroup) | ||
213 | { | ||
214 | int ret; | ||
215 | |||
216 | retry: | ||
217 | ret = rmdir(cgroup); | ||
218 | if (ret && errno == EBUSY) { | ||
219 | ret = cg_killall(cgroup); | ||
220 | if (ret) | ||
221 | return ret; | ||
222 | usleep(100); | ||
223 | goto retry; | ||
224 | } | ||
225 | |||
226 | if (ret && errno == ENOENT) | ||
227 | ret = 0; | ||
228 | |||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | int cg_run(const char *cgroup, | ||
233 | int (*fn)(const char *cgroup, void *arg), | ||
234 | void *arg) | ||
235 | { | ||
236 | int pid, retcode; | ||
237 | |||
238 | pid = fork(); | ||
239 | if (pid < 0) { | ||
240 | return pid; | ||
241 | } else if (pid == 0) { | ||
242 | char buf[64]; | ||
243 | |||
244 | snprintf(buf, sizeof(buf), "%d", getpid()); | ||
245 | if (cg_write(cgroup, "cgroup.procs", buf)) | ||
246 | exit(EXIT_FAILURE); | ||
247 | exit(fn(cgroup, arg)); | ||
248 | } else { | ||
249 | waitpid(pid, &retcode, 0); | ||
250 | if (WIFEXITED(retcode)) | ||
251 | return WEXITSTATUS(retcode); | ||
252 | else | ||
253 | return -1; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | int cg_run_nowait(const char *cgroup, | ||
258 | int (*fn)(const char *cgroup, void *arg), | ||
259 | void *arg) | ||
260 | { | ||
261 | int pid; | ||
262 | |||
263 | pid = fork(); | ||
264 | if (pid == 0) { | ||
265 | char buf[64]; | ||
266 | |||
267 | snprintf(buf, sizeof(buf), "%d", getpid()); | ||
268 | if (cg_write(cgroup, "cgroup.procs", buf)) | ||
269 | exit(EXIT_FAILURE); | ||
270 | exit(fn(cgroup, arg)); | ||
271 | } | ||
272 | |||
273 | return pid; | ||
274 | } | ||
275 | |||
276 | int get_temp_fd(void) | ||
277 | { | ||
278 | return open(".", O_TMPFILE | O_RDWR | O_EXCL); | ||
279 | } | ||
280 | |||
281 | int alloc_pagecache(int fd, size_t size) | ||
282 | { | ||
283 | char buf[PAGE_SIZE]; | ||
284 | struct stat st; | ||
285 | int i; | ||
286 | |||
287 | if (fstat(fd, &st)) | ||
288 | goto cleanup; | ||
289 | |||
290 | size += st.st_size; | ||
291 | |||
292 | if (ftruncate(fd, size)) | ||
293 | goto cleanup; | ||
294 | |||
295 | for (i = 0; i < size; i += sizeof(buf)) | ||
296 | read(fd, buf, sizeof(buf)); | ||
297 | |||
298 | return 0; | ||
299 | |||
300 | cleanup: | ||
301 | return -1; | ||
302 | } | ||
303 | |||
304 | int alloc_anon(const char *cgroup, void *arg) | ||
305 | { | ||
306 | size_t size = (unsigned long)arg; | ||
307 | char *buf, *ptr; | ||
308 | |||
309 | buf = malloc(size); | ||
310 | for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE) | ||
311 | *ptr = 0; | ||
312 | |||
313 | free(buf); | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | int is_swap_enabled(void) | ||
318 | { | ||
319 | char buf[PAGE_SIZE]; | ||
320 | const char delim[] = "\n"; | ||
321 | int cnt = 0; | ||
322 | char *line; | ||
323 | |||
324 | if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0) | ||
325 | return -1; | ||
326 | |||
327 | for (line = strtok(buf, delim); line; line = strtok(NULL, delim)) | ||
328 | cnt++; | ||
329 | |||
330 | return cnt > 1; | ||
331 | } | ||
diff --git a/tools/testing/selftests/cgroup/cgroup_util.h b/tools/testing/selftests/cgroup/cgroup_util.h new file mode 100644 index 000000000000..fe82a297d4e0 --- /dev/null +++ b/tools/testing/selftests/cgroup/cgroup_util.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #include <stdlib.h> | ||
3 | |||
4 | #define PAGE_SIZE 4096 | ||
5 | |||
6 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | ||
7 | |||
8 | #define MB(x) (x << 20) | ||
9 | |||
10 | /* | ||
11 | * Checks if two given values differ by less than err% of their sum. | ||
12 | */ | ||
13 | static inline int values_close(long a, long b, int err) | ||
14 | { | ||
15 | return abs(a - b) <= (a + b) / 100 * err; | ||
16 | } | ||
17 | |||
18 | extern int cg_find_unified_root(char *root, size_t len); | ||
19 | extern char *cg_name(const char *root, const char *name); | ||
20 | extern char *cg_name_indexed(const char *root, const char *name, int index); | ||
21 | extern int cg_create(const char *cgroup); | ||
22 | extern int cg_destroy(const char *cgroup); | ||
23 | extern int cg_read(const char *cgroup, const char *control, | ||
24 | char *buf, size_t len); | ||
25 | extern int cg_read_strcmp(const char *cgroup, const char *control, | ||
26 | const char *expected); | ||
27 | extern int cg_read_strstr(const char *cgroup, const char *control, | ||
28 | const char *needle); | ||
29 | extern long cg_read_long(const char *cgroup, const char *control); | ||
30 | long cg_read_key_long(const char *cgroup, const char *control, const char *key); | ||
31 | extern int cg_write(const char *cgroup, const char *control, char *buf); | ||
32 | extern int cg_run(const char *cgroup, | ||
33 | int (*fn)(const char *cgroup, void *arg), | ||
34 | void *arg); | ||
35 | extern int cg_run_nowait(const char *cgroup, | ||
36 | int (*fn)(const char *cgroup, void *arg), | ||
37 | void *arg); | ||
38 | extern int get_temp_fd(void); | ||
39 | extern int alloc_pagecache(int fd, size_t size); | ||
40 | extern int alloc_anon(const char *cgroup, void *arg); | ||
41 | extern int is_swap_enabled(void); | ||
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c new file mode 100644 index 000000000000..cf0bddc9d271 --- /dev/null +++ b/tools/testing/selftests/cgroup/test_memcontrol.c | |||
@@ -0,0 +1,1015 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #define _GNU_SOURCE | ||
3 | |||
4 | #include <linux/limits.h> | ||
5 | #include <fcntl.h> | ||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | #include <sys/stat.h> | ||
10 | #include <sys/types.h> | ||
11 | #include <unistd.h> | ||
12 | #include <sys/socket.h> | ||
13 | #include <sys/wait.h> | ||
14 | #include <arpa/inet.h> | ||
15 | #include <netinet/in.h> | ||
16 | #include <netdb.h> | ||
17 | #include <errno.h> | ||
18 | |||
19 | #include "../kselftest.h" | ||
20 | #include "cgroup_util.h" | ||
21 | |||
22 | /* | ||
23 | * This test creates two nested cgroups with and without enabling | ||
24 | * the memory controller. | ||
25 | */ | ||
26 | static int test_memcg_subtree_control(const char *root) | ||
27 | { | ||
28 | char *parent, *child, *parent2, *child2; | ||
29 | int ret = KSFT_FAIL; | ||
30 | char buf[PAGE_SIZE]; | ||
31 | |||
32 | /* Create two nested cgroups with the memory controller enabled */ | ||
33 | parent = cg_name(root, "memcg_test_0"); | ||
34 | child = cg_name(root, "memcg_test_0/memcg_test_1"); | ||
35 | if (!parent || !child) | ||
36 | goto cleanup; | ||
37 | |||
38 | if (cg_create(parent)) | ||
39 | goto cleanup; | ||
40 | |||
41 | if (cg_write(parent, "cgroup.subtree_control", "+memory")) | ||
42 | goto cleanup; | ||
43 | |||
44 | if (cg_create(child)) | ||
45 | goto cleanup; | ||
46 | |||
47 | if (cg_read_strstr(child, "cgroup.controllers", "memory")) | ||
48 | goto cleanup; | ||
49 | |||
50 | /* Create two nested cgroups without enabling memory controller */ | ||
51 | parent2 = cg_name(root, "memcg_test_1"); | ||
52 | child2 = cg_name(root, "memcg_test_1/memcg_test_1"); | ||
53 | if (!parent2 || !child2) | ||
54 | goto cleanup; | ||
55 | |||
56 | if (cg_create(parent2)) | ||
57 | goto cleanup; | ||
58 | |||
59 | if (cg_create(child2)) | ||
60 | goto cleanup; | ||
61 | |||
62 | if (cg_read(child2, "cgroup.controllers", buf, sizeof(buf))) | ||
63 | goto cleanup; | ||
64 | |||
65 | if (!cg_read_strstr(child2, "cgroup.controllers", "memory")) | ||
66 | goto cleanup; | ||
67 | |||
68 | ret = KSFT_PASS; | ||
69 | |||
70 | cleanup: | ||
71 | cg_destroy(child); | ||
72 | cg_destroy(parent); | ||
73 | free(parent); | ||
74 | free(child); | ||
75 | |||
76 | cg_destroy(child2); | ||
77 | cg_destroy(parent2); | ||
78 | free(parent2); | ||
79 | free(child2); | ||
80 | |||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | static int alloc_anon_50M_check(const char *cgroup, void *arg) | ||
85 | { | ||
86 | size_t size = MB(50); | ||
87 | char *buf, *ptr; | ||
88 | long anon, current; | ||
89 | int ret = -1; | ||
90 | |||
91 | buf = malloc(size); | ||
92 | for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE) | ||
93 | *ptr = 0; | ||
94 | |||
95 | current = cg_read_long(cgroup, "memory.current"); | ||
96 | if (current < size) | ||
97 | goto cleanup; | ||
98 | |||
99 | if (!values_close(size, current, 3)) | ||
100 | goto cleanup; | ||
101 | |||
102 | anon = cg_read_key_long(cgroup, "memory.stat", "anon "); | ||
103 | if (anon < 0) | ||
104 | goto cleanup; | ||
105 | |||
106 | if (!values_close(anon, current, 3)) | ||
107 | goto cleanup; | ||
108 | |||
109 | ret = 0; | ||
110 | cleanup: | ||
111 | free(buf); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | static int alloc_pagecache_50M_check(const char *cgroup, void *arg) | ||
116 | { | ||
117 | size_t size = MB(50); | ||
118 | int ret = -1; | ||
119 | long current, file; | ||
120 | int fd; | ||
121 | |||
122 | fd = get_temp_fd(); | ||
123 | if (fd < 0) | ||
124 | return -1; | ||
125 | |||
126 | if (alloc_pagecache(fd, size)) | ||
127 | goto cleanup; | ||
128 | |||
129 | current = cg_read_long(cgroup, "memory.current"); | ||
130 | if (current < size) | ||
131 | goto cleanup; | ||
132 | |||
133 | file = cg_read_key_long(cgroup, "memory.stat", "file "); | ||
134 | if (file < 0) | ||
135 | goto cleanup; | ||
136 | |||
137 | if (!values_close(file, current, 10)) | ||
138 | goto cleanup; | ||
139 | |||
140 | ret = 0; | ||
141 | |||
142 | cleanup: | ||
143 | close(fd); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * This test create a memory cgroup, allocates | ||
149 | * some anonymous memory and some pagecache | ||
150 | * and check memory.current and some memory.stat values. | ||
151 | */ | ||
152 | static int test_memcg_current(const char *root) | ||
153 | { | ||
154 | int ret = KSFT_FAIL; | ||
155 | long current; | ||
156 | char *memcg; | ||
157 | |||
158 | memcg = cg_name(root, "memcg_test"); | ||
159 | if (!memcg) | ||
160 | goto cleanup; | ||
161 | |||
162 | if (cg_create(memcg)) | ||
163 | goto cleanup; | ||
164 | |||
165 | current = cg_read_long(memcg, "memory.current"); | ||
166 | if (current != 0) | ||
167 | goto cleanup; | ||
168 | |||
169 | if (cg_run(memcg, alloc_anon_50M_check, NULL)) | ||
170 | goto cleanup; | ||
171 | |||
172 | if (cg_run(memcg, alloc_pagecache_50M_check, NULL)) | ||
173 | goto cleanup; | ||
174 | |||
175 | ret = KSFT_PASS; | ||
176 | |||
177 | cleanup: | ||
178 | cg_destroy(memcg); | ||
179 | free(memcg); | ||
180 | |||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static int alloc_pagecache_50M(const char *cgroup, void *arg) | ||
185 | { | ||
186 | int fd = (long)arg; | ||
187 | |||
188 | return alloc_pagecache(fd, MB(50)); | ||
189 | } | ||
190 | |||
191 | static int alloc_pagecache_50M_noexit(const char *cgroup, void *arg) | ||
192 | { | ||
193 | int fd = (long)arg; | ||
194 | int ppid = getppid(); | ||
195 | |||
196 | if (alloc_pagecache(fd, MB(50))) | ||
197 | return -1; | ||
198 | |||
199 | while (getppid() == ppid) | ||
200 | sleep(1); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * First, this test creates the following hierarchy: | ||
207 | * A memory.min = 50M, memory.max = 200M | ||
208 | * A/B memory.min = 50M, memory.current = 50M | ||
209 | * A/B/C memory.min = 75M, memory.current = 50M | ||
210 | * A/B/D memory.min = 25M, memory.current = 50M | ||
211 | * A/B/E memory.min = 500M, memory.current = 0 | ||
212 | * A/B/F memory.min = 0, memory.current = 50M | ||
213 | * | ||
214 | * Usages are pagecache, but the test keeps a running | ||
215 | * process in every leaf cgroup. | ||
216 | * Then it creates A/G and creates a significant | ||
217 | * memory pressure in it. | ||
218 | * | ||
219 | * A/B memory.current ~= 50M | ||
220 | * A/B/C memory.current ~= 33M | ||
221 | * A/B/D memory.current ~= 17M | ||
222 | * A/B/E memory.current ~= 0 | ||
223 | * | ||
224 | * After that it tries to allocate more than there is | ||
225 | * unprotected memory in A available, and checks | ||
226 | * checks that memory.min protects pagecache even | ||
227 | * in this case. | ||
228 | */ | ||
229 | static int test_memcg_min(const char *root) | ||
230 | { | ||
231 | int ret = KSFT_FAIL; | ||
232 | char *parent[3] = {NULL}; | ||
233 | char *children[4] = {NULL}; | ||
234 | long c[4]; | ||
235 | int i, attempts; | ||
236 | int fd; | ||
237 | |||
238 | fd = get_temp_fd(); | ||
239 | if (fd < 0) | ||
240 | goto cleanup; | ||
241 | |||
242 | parent[0] = cg_name(root, "memcg_test_0"); | ||
243 | if (!parent[0]) | ||
244 | goto cleanup; | ||
245 | |||
246 | parent[1] = cg_name(parent[0], "memcg_test_1"); | ||
247 | if (!parent[1]) | ||
248 | goto cleanup; | ||
249 | |||
250 | parent[2] = cg_name(parent[0], "memcg_test_2"); | ||
251 | if (!parent[2]) | ||
252 | goto cleanup; | ||
253 | |||
254 | if (cg_create(parent[0])) | ||
255 | goto cleanup; | ||
256 | |||
257 | if (cg_read_long(parent[0], "memory.min")) { | ||
258 | ret = KSFT_SKIP; | ||
259 | goto cleanup; | ||
260 | } | ||
261 | |||
262 | if (cg_write(parent[0], "cgroup.subtree_control", "+memory")) | ||
263 | goto cleanup; | ||
264 | |||
265 | if (cg_write(parent[0], "memory.max", "200M")) | ||
266 | goto cleanup; | ||
267 | |||
268 | if (cg_write(parent[0], "memory.swap.max", "0")) | ||
269 | goto cleanup; | ||
270 | |||
271 | if (cg_create(parent[1])) | ||
272 | goto cleanup; | ||
273 | |||
274 | if (cg_write(parent[1], "cgroup.subtree_control", "+memory")) | ||
275 | goto cleanup; | ||
276 | |||
277 | if (cg_create(parent[2])) | ||
278 | goto cleanup; | ||
279 | |||
280 | for (i = 0; i < ARRAY_SIZE(children); i++) { | ||
281 | children[i] = cg_name_indexed(parent[1], "child_memcg", i); | ||
282 | if (!children[i]) | ||
283 | goto cleanup; | ||
284 | |||
285 | if (cg_create(children[i])) | ||
286 | goto cleanup; | ||
287 | |||
288 | if (i == 2) | ||
289 | continue; | ||
290 | |||
291 | cg_run_nowait(children[i], alloc_pagecache_50M_noexit, | ||
292 | (void *)(long)fd); | ||
293 | } | ||
294 | |||
295 | if (cg_write(parent[0], "memory.min", "50M")) | ||
296 | goto cleanup; | ||
297 | if (cg_write(parent[1], "memory.min", "50M")) | ||
298 | goto cleanup; | ||
299 | if (cg_write(children[0], "memory.min", "75M")) | ||
300 | goto cleanup; | ||
301 | if (cg_write(children[1], "memory.min", "25M")) | ||
302 | goto cleanup; | ||
303 | if (cg_write(children[2], "memory.min", "500M")) | ||
304 | goto cleanup; | ||
305 | if (cg_write(children[3], "memory.min", "0")) | ||
306 | goto cleanup; | ||
307 | |||
308 | attempts = 0; | ||
309 | while (!values_close(cg_read_long(parent[1], "memory.current"), | ||
310 | MB(150), 3)) { | ||
311 | if (attempts++ > 5) | ||
312 | break; | ||
313 | sleep(1); | ||
314 | } | ||
315 | |||
316 | if (cg_run(parent[2], alloc_anon, (void *)MB(148))) | ||
317 | goto cleanup; | ||
318 | |||
319 | if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3)) | ||
320 | goto cleanup; | ||
321 | |||
322 | for (i = 0; i < ARRAY_SIZE(children); i++) | ||
323 | c[i] = cg_read_long(children[i], "memory.current"); | ||
324 | |||
325 | if (!values_close(c[0], MB(33), 10)) | ||
326 | goto cleanup; | ||
327 | |||
328 | if (!values_close(c[1], MB(17), 10)) | ||
329 | goto cleanup; | ||
330 | |||
331 | if (!values_close(c[2], 0, 1)) | ||
332 | goto cleanup; | ||
333 | |||
334 | if (!cg_run(parent[2], alloc_anon, (void *)MB(170))) | ||
335 | goto cleanup; | ||
336 | |||
337 | if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3)) | ||
338 | goto cleanup; | ||
339 | |||
340 | ret = KSFT_PASS; | ||
341 | |||
342 | cleanup: | ||
343 | for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) { | ||
344 | if (!children[i]) | ||
345 | continue; | ||
346 | |||
347 | cg_destroy(children[i]); | ||
348 | free(children[i]); | ||
349 | } | ||
350 | |||
351 | for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) { | ||
352 | if (!parent[i]) | ||
353 | continue; | ||
354 | |||
355 | cg_destroy(parent[i]); | ||
356 | free(parent[i]); | ||
357 | } | ||
358 | close(fd); | ||
359 | return ret; | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * First, this test creates the following hierarchy: | ||
364 | * A memory.low = 50M, memory.max = 200M | ||
365 | * A/B memory.low = 50M, memory.current = 50M | ||
366 | * A/B/C memory.low = 75M, memory.current = 50M | ||
367 | * A/B/D memory.low = 25M, memory.current = 50M | ||
368 | * A/B/E memory.low = 500M, memory.current = 0 | ||
369 | * A/B/F memory.low = 0, memory.current = 50M | ||
370 | * | ||
371 | * Usages are pagecache. | ||
372 | * Then it creates A/G an creates a significant | ||
373 | * memory pressure in it. | ||
374 | * | ||
375 | * Then it checks actual memory usages and expects that: | ||
376 | * A/B memory.current ~= 50M | ||
377 | * A/B/ memory.current ~= 33M | ||
378 | * A/B/D memory.current ~= 17M | ||
379 | * A/B/E memory.current ~= 0 | ||
380 | * | ||
381 | * After that it tries to allocate more than there is | ||
382 | * unprotected memory in A available, | ||
383 | * and checks low and oom events in memory.events. | ||
384 | */ | ||
385 | static int test_memcg_low(const char *root) | ||
386 | { | ||
387 | int ret = KSFT_FAIL; | ||
388 | char *parent[3] = {NULL}; | ||
389 | char *children[4] = {NULL}; | ||
390 | long low, oom; | ||
391 | long c[4]; | ||
392 | int i; | ||
393 | int fd; | ||
394 | |||
395 | fd = get_temp_fd(); | ||
396 | if (fd < 0) | ||
397 | goto cleanup; | ||
398 | |||
399 | parent[0] = cg_name(root, "memcg_test_0"); | ||
400 | if (!parent[0]) | ||
401 | goto cleanup; | ||
402 | |||
403 | parent[1] = cg_name(parent[0], "memcg_test_1"); | ||
404 | if (!parent[1]) | ||
405 | goto cleanup; | ||
406 | |||
407 | parent[2] = cg_name(parent[0], "memcg_test_2"); | ||
408 | if (!parent[2]) | ||
409 | goto cleanup; | ||
410 | |||
411 | if (cg_create(parent[0])) | ||
412 | goto cleanup; | ||
413 | |||
414 | if (cg_read_long(parent[0], "memory.low")) | ||
415 | goto cleanup; | ||
416 | |||
417 | if (cg_write(parent[0], "cgroup.subtree_control", "+memory")) | ||
418 | goto cleanup; | ||
419 | |||
420 | if (cg_write(parent[0], "memory.max", "200M")) | ||
421 | goto cleanup; | ||
422 | |||
423 | if (cg_write(parent[0], "memory.swap.max", "0")) | ||
424 | goto cleanup; | ||
425 | |||
426 | if (cg_create(parent[1])) | ||
427 | goto cleanup; | ||
428 | |||
429 | if (cg_write(parent[1], "cgroup.subtree_control", "+memory")) | ||
430 | goto cleanup; | ||
431 | |||
432 | if (cg_create(parent[2])) | ||
433 | goto cleanup; | ||
434 | |||
435 | for (i = 0; i < ARRAY_SIZE(children); i++) { | ||
436 | children[i] = cg_name_indexed(parent[1], "child_memcg", i); | ||
437 | if (!children[i]) | ||
438 | goto cleanup; | ||
439 | |||
440 | if (cg_create(children[i])) | ||
441 | goto cleanup; | ||
442 | |||
443 | if (i == 2) | ||
444 | continue; | ||
445 | |||
446 | if (cg_run(children[i], alloc_pagecache_50M, (void *)(long)fd)) | ||
447 | goto cleanup; | ||
448 | } | ||
449 | |||
450 | if (cg_write(parent[0], "memory.low", "50M")) | ||
451 | goto cleanup; | ||
452 | if (cg_write(parent[1], "memory.low", "50M")) | ||
453 | goto cleanup; | ||
454 | if (cg_write(children[0], "memory.low", "75M")) | ||
455 | goto cleanup; | ||
456 | if (cg_write(children[1], "memory.low", "25M")) | ||
457 | goto cleanup; | ||
458 | if (cg_write(children[2], "memory.low", "500M")) | ||
459 | goto cleanup; | ||
460 | if (cg_write(children[3], "memory.low", "0")) | ||
461 | goto cleanup; | ||
462 | |||
463 | if (cg_run(parent[2], alloc_anon, (void *)MB(148))) | ||
464 | goto cleanup; | ||
465 | |||
466 | if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3)) | ||
467 | goto cleanup; | ||
468 | |||
469 | for (i = 0; i < ARRAY_SIZE(children); i++) | ||
470 | c[i] = cg_read_long(children[i], "memory.current"); | ||
471 | |||
472 | if (!values_close(c[0], MB(33), 10)) | ||
473 | goto cleanup; | ||
474 | |||
475 | if (!values_close(c[1], MB(17), 10)) | ||
476 | goto cleanup; | ||
477 | |||
478 | if (!values_close(c[2], 0, 1)) | ||
479 | goto cleanup; | ||
480 | |||
481 | if (cg_run(parent[2], alloc_anon, (void *)MB(166))) { | ||
482 | fprintf(stderr, | ||
483 | "memory.low prevents from allocating anon memory\n"); | ||
484 | goto cleanup; | ||
485 | } | ||
486 | |||
487 | for (i = 0; i < ARRAY_SIZE(children); i++) { | ||
488 | oom = cg_read_key_long(children[i], "memory.events", "oom "); | ||
489 | low = cg_read_key_long(children[i], "memory.events", "low "); | ||
490 | |||
491 | if (oom) | ||
492 | goto cleanup; | ||
493 | if (i < 2 && low <= 0) | ||
494 | goto cleanup; | ||
495 | if (i >= 2 && low) | ||
496 | goto cleanup; | ||
497 | } | ||
498 | |||
499 | ret = KSFT_PASS; | ||
500 | |||
501 | cleanup: | ||
502 | for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) { | ||
503 | if (!children[i]) | ||
504 | continue; | ||
505 | |||
506 | cg_destroy(children[i]); | ||
507 | free(children[i]); | ||
508 | } | ||
509 | |||
510 | for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) { | ||
511 | if (!parent[i]) | ||
512 | continue; | ||
513 | |||
514 | cg_destroy(parent[i]); | ||
515 | free(parent[i]); | ||
516 | } | ||
517 | close(fd); | ||
518 | return ret; | ||
519 | } | ||
520 | |||
521 | static int alloc_pagecache_max_30M(const char *cgroup, void *arg) | ||
522 | { | ||
523 | size_t size = MB(50); | ||
524 | int ret = -1; | ||
525 | long current; | ||
526 | int fd; | ||
527 | |||
528 | fd = get_temp_fd(); | ||
529 | if (fd < 0) | ||
530 | return -1; | ||
531 | |||
532 | if (alloc_pagecache(fd, size)) | ||
533 | goto cleanup; | ||
534 | |||
535 | current = cg_read_long(cgroup, "memory.current"); | ||
536 | if (current <= MB(29) || current > MB(30)) | ||
537 | goto cleanup; | ||
538 | |||
539 | ret = 0; | ||
540 | |||
541 | cleanup: | ||
542 | close(fd); | ||
543 | return ret; | ||
544 | |||
545 | } | ||
546 | |||
547 | /* | ||
548 | * This test checks that memory.high limits the amount of | ||
549 | * memory which can be consumed by either anonymous memory | ||
550 | * or pagecache. | ||
551 | */ | ||
552 | static int test_memcg_high(const char *root) | ||
553 | { | ||
554 | int ret = KSFT_FAIL; | ||
555 | char *memcg; | ||
556 | long high; | ||
557 | |||
558 | memcg = cg_name(root, "memcg_test"); | ||
559 | if (!memcg) | ||
560 | goto cleanup; | ||
561 | |||
562 | if (cg_create(memcg)) | ||
563 | goto cleanup; | ||
564 | |||
565 | if (cg_read_strcmp(memcg, "memory.high", "max\n")) | ||
566 | goto cleanup; | ||
567 | |||
568 | if (cg_write(memcg, "memory.swap.max", "0")) | ||
569 | goto cleanup; | ||
570 | |||
571 | if (cg_write(memcg, "memory.high", "30M")) | ||
572 | goto cleanup; | ||
573 | |||
574 | if (cg_run(memcg, alloc_anon, (void *)MB(100))) | ||
575 | goto cleanup; | ||
576 | |||
577 | if (!cg_run(memcg, alloc_pagecache_50M_check, NULL)) | ||
578 | goto cleanup; | ||
579 | |||
580 | if (cg_run(memcg, alloc_pagecache_max_30M, NULL)) | ||
581 | goto cleanup; | ||
582 | |||
583 | high = cg_read_key_long(memcg, "memory.events", "high "); | ||
584 | if (high <= 0) | ||
585 | goto cleanup; | ||
586 | |||
587 | ret = KSFT_PASS; | ||
588 | |||
589 | cleanup: | ||
590 | cg_destroy(memcg); | ||
591 | free(memcg); | ||
592 | |||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * This test checks that memory.max limits the amount of | ||
598 | * memory which can be consumed by either anonymous memory | ||
599 | * or pagecache. | ||
600 | */ | ||
601 | static int test_memcg_max(const char *root) | ||
602 | { | ||
603 | int ret = KSFT_FAIL; | ||
604 | char *memcg; | ||
605 | long current, max; | ||
606 | |||
607 | memcg = cg_name(root, "memcg_test"); | ||
608 | if (!memcg) | ||
609 | goto cleanup; | ||
610 | |||
611 | if (cg_create(memcg)) | ||
612 | goto cleanup; | ||
613 | |||
614 | if (cg_read_strcmp(memcg, "memory.max", "max\n")) | ||
615 | goto cleanup; | ||
616 | |||
617 | if (cg_write(memcg, "memory.swap.max", "0")) | ||
618 | goto cleanup; | ||
619 | |||
620 | if (cg_write(memcg, "memory.max", "30M")) | ||
621 | goto cleanup; | ||
622 | |||
623 | /* Should be killed by OOM killer */ | ||
624 | if (!cg_run(memcg, alloc_anon, (void *)MB(100))) | ||
625 | goto cleanup; | ||
626 | |||
627 | if (cg_run(memcg, alloc_pagecache_max_30M, NULL)) | ||
628 | goto cleanup; | ||
629 | |||
630 | current = cg_read_long(memcg, "memory.current"); | ||
631 | if (current > MB(30) || !current) | ||
632 | goto cleanup; | ||
633 | |||
634 | max = cg_read_key_long(memcg, "memory.events", "max "); | ||
635 | if (max <= 0) | ||
636 | goto cleanup; | ||
637 | |||
638 | ret = KSFT_PASS; | ||
639 | |||
640 | cleanup: | ||
641 | cg_destroy(memcg); | ||
642 | free(memcg); | ||
643 | |||
644 | return ret; | ||
645 | } | ||
646 | |||
647 | static int alloc_anon_50M_check_swap(const char *cgroup, void *arg) | ||
648 | { | ||
649 | long mem_max = (long)arg; | ||
650 | size_t size = MB(50); | ||
651 | char *buf, *ptr; | ||
652 | long mem_current, swap_current; | ||
653 | int ret = -1; | ||
654 | |||
655 | buf = malloc(size); | ||
656 | for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE) | ||
657 | *ptr = 0; | ||
658 | |||
659 | mem_current = cg_read_long(cgroup, "memory.current"); | ||
660 | if (!mem_current || !values_close(mem_current, mem_max, 3)) | ||
661 | goto cleanup; | ||
662 | |||
663 | swap_current = cg_read_long(cgroup, "memory.swap.current"); | ||
664 | if (!swap_current || | ||
665 | !values_close(mem_current + swap_current, size, 3)) | ||
666 | goto cleanup; | ||
667 | |||
668 | ret = 0; | ||
669 | cleanup: | ||
670 | free(buf); | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | /* | ||
675 | * This test checks that memory.swap.max limits the amount of | ||
676 | * anonymous memory which can be swapped out. | ||
677 | */ | ||
678 | static int test_memcg_swap_max(const char *root) | ||
679 | { | ||
680 | int ret = KSFT_FAIL; | ||
681 | char *memcg; | ||
682 | long max; | ||
683 | |||
684 | if (!is_swap_enabled()) | ||
685 | return KSFT_SKIP; | ||
686 | |||
687 | memcg = cg_name(root, "memcg_test"); | ||
688 | if (!memcg) | ||
689 | goto cleanup; | ||
690 | |||
691 | if (cg_create(memcg)) | ||
692 | goto cleanup; | ||
693 | |||
694 | if (cg_read_long(memcg, "memory.swap.current")) { | ||
695 | ret = KSFT_SKIP; | ||
696 | goto cleanup; | ||
697 | } | ||
698 | |||
699 | if (cg_read_strcmp(memcg, "memory.max", "max\n")) | ||
700 | goto cleanup; | ||
701 | |||
702 | if (cg_read_strcmp(memcg, "memory.swap.max", "max\n")) | ||
703 | goto cleanup; | ||
704 | |||
705 | if (cg_write(memcg, "memory.swap.max", "30M")) | ||
706 | goto cleanup; | ||
707 | |||
708 | if (cg_write(memcg, "memory.max", "30M")) | ||
709 | goto cleanup; | ||
710 | |||
711 | /* Should be killed by OOM killer */ | ||
712 | if (!cg_run(memcg, alloc_anon, (void *)MB(100))) | ||
713 | goto cleanup; | ||
714 | |||
715 | if (cg_read_key_long(memcg, "memory.events", "oom ") != 1) | ||
716 | goto cleanup; | ||
717 | |||
718 | if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1) | ||
719 | goto cleanup; | ||
720 | |||
721 | if (cg_run(memcg, alloc_anon_50M_check_swap, (void *)MB(30))) | ||
722 | goto cleanup; | ||
723 | |||
724 | max = cg_read_key_long(memcg, "memory.events", "max "); | ||
725 | if (max <= 0) | ||
726 | goto cleanup; | ||
727 | |||
728 | ret = KSFT_PASS; | ||
729 | |||
730 | cleanup: | ||
731 | cg_destroy(memcg); | ||
732 | free(memcg); | ||
733 | |||
734 | return ret; | ||
735 | } | ||
736 | |||
737 | /* | ||
738 | * This test disables swapping and tries to allocate anonymous memory | ||
739 | * up to OOM. Then it checks for oom and oom_kill events in | ||
740 | * memory.events. | ||
741 | */ | ||
742 | static int test_memcg_oom_events(const char *root) | ||
743 | { | ||
744 | int ret = KSFT_FAIL; | ||
745 | char *memcg; | ||
746 | |||
747 | memcg = cg_name(root, "memcg_test"); | ||
748 | if (!memcg) | ||
749 | goto cleanup; | ||
750 | |||
751 | if (cg_create(memcg)) | ||
752 | goto cleanup; | ||
753 | |||
754 | if (cg_write(memcg, "memory.max", "30M")) | ||
755 | goto cleanup; | ||
756 | |||
757 | if (cg_write(memcg, "memory.swap.max", "0")) | ||
758 | goto cleanup; | ||
759 | |||
760 | if (!cg_run(memcg, alloc_anon, (void *)MB(100))) | ||
761 | goto cleanup; | ||
762 | |||
763 | if (cg_read_strcmp(memcg, "cgroup.procs", "")) | ||
764 | goto cleanup; | ||
765 | |||
766 | if (cg_read_key_long(memcg, "memory.events", "oom ") != 1) | ||
767 | goto cleanup; | ||
768 | |||
769 | if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1) | ||
770 | goto cleanup; | ||
771 | |||
772 | ret = KSFT_PASS; | ||
773 | |||
774 | cleanup: | ||
775 | cg_destroy(memcg); | ||
776 | free(memcg); | ||
777 | |||
778 | return ret; | ||
779 | } | ||
780 | |||
781 | struct tcp_server_args { | ||
782 | unsigned short port; | ||
783 | int ctl[2]; | ||
784 | }; | ||
785 | |||
786 | static int tcp_server(const char *cgroup, void *arg) | ||
787 | { | ||
788 | struct tcp_server_args *srv_args = arg; | ||
789 | struct sockaddr_in6 saddr = { 0 }; | ||
790 | socklen_t slen = sizeof(saddr); | ||
791 | int sk, client_sk, ctl_fd, yes = 1, ret = -1; | ||
792 | |||
793 | close(srv_args->ctl[0]); | ||
794 | ctl_fd = srv_args->ctl[1]; | ||
795 | |||
796 | saddr.sin6_family = AF_INET6; | ||
797 | saddr.sin6_addr = in6addr_any; | ||
798 | saddr.sin6_port = htons(srv_args->port); | ||
799 | |||
800 | sk = socket(AF_INET6, SOCK_STREAM, 0); | ||
801 | if (sk < 0) | ||
802 | return ret; | ||
803 | |||
804 | if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) | ||
805 | goto cleanup; | ||
806 | |||
807 | if (bind(sk, (struct sockaddr *)&saddr, slen)) { | ||
808 | write(ctl_fd, &errno, sizeof(errno)); | ||
809 | goto cleanup; | ||
810 | } | ||
811 | |||
812 | if (listen(sk, 1)) | ||
813 | goto cleanup; | ||
814 | |||
815 | ret = 0; | ||
816 | if (write(ctl_fd, &ret, sizeof(ret)) != sizeof(ret)) { | ||
817 | ret = -1; | ||
818 | goto cleanup; | ||
819 | } | ||
820 | |||
821 | client_sk = accept(sk, NULL, NULL); | ||
822 | if (client_sk < 0) | ||
823 | goto cleanup; | ||
824 | |||
825 | ret = -1; | ||
826 | for (;;) { | ||
827 | uint8_t buf[0x100000]; | ||
828 | |||
829 | if (write(client_sk, buf, sizeof(buf)) <= 0) { | ||
830 | if (errno == ECONNRESET) | ||
831 | ret = 0; | ||
832 | break; | ||
833 | } | ||
834 | } | ||
835 | |||
836 | close(client_sk); | ||
837 | |||
838 | cleanup: | ||
839 | close(sk); | ||
840 | return ret; | ||
841 | } | ||
842 | |||
843 | static int tcp_client(const char *cgroup, unsigned short port) | ||
844 | { | ||
845 | const char server[] = "localhost"; | ||
846 | struct addrinfo *ai; | ||
847 | char servport[6]; | ||
848 | int retries = 0x10; /* nice round number */ | ||
849 | int sk, ret; | ||
850 | |||
851 | snprintf(servport, sizeof(servport), "%hd", port); | ||
852 | ret = getaddrinfo(server, servport, NULL, &ai); | ||
853 | if (ret) | ||
854 | return ret; | ||
855 | |||
856 | sk = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | ||
857 | if (sk < 0) | ||
858 | goto free_ainfo; | ||
859 | |||
860 | ret = connect(sk, ai->ai_addr, ai->ai_addrlen); | ||
861 | if (ret < 0) | ||
862 | goto close_sk; | ||
863 | |||
864 | ret = KSFT_FAIL; | ||
865 | while (retries--) { | ||
866 | uint8_t buf[0x100000]; | ||
867 | long current, sock; | ||
868 | |||
869 | if (read(sk, buf, sizeof(buf)) <= 0) | ||
870 | goto close_sk; | ||
871 | |||
872 | current = cg_read_long(cgroup, "memory.current"); | ||
873 | sock = cg_read_key_long(cgroup, "memory.stat", "sock "); | ||
874 | |||
875 | if (current < 0 || sock < 0) | ||
876 | goto close_sk; | ||
877 | |||
878 | if (current < sock) | ||
879 | goto close_sk; | ||
880 | |||
881 | if (values_close(current, sock, 10)) { | ||
882 | ret = KSFT_PASS; | ||
883 | break; | ||
884 | } | ||
885 | } | ||
886 | |||
887 | close_sk: | ||
888 | close(sk); | ||
889 | free_ainfo: | ||
890 | freeaddrinfo(ai); | ||
891 | return ret; | ||
892 | } | ||
893 | |||
894 | /* | ||
895 | * This test checks socket memory accounting. | ||
896 | * The test forks a TCP server listens on a random port between 1000 | ||
897 | * and 61000. Once it gets a client connection, it starts writing to | ||
898 | * its socket. | ||
899 | * The TCP client interleaves reads from the socket with check whether | ||
900 | * memory.current and memory.stat.sock are similar. | ||
901 | */ | ||
902 | static int test_memcg_sock(const char *root) | ||
903 | { | ||
904 | int bind_retries = 5, ret = KSFT_FAIL, pid, err; | ||
905 | unsigned short port; | ||
906 | char *memcg; | ||
907 | |||
908 | memcg = cg_name(root, "memcg_test"); | ||
909 | if (!memcg) | ||
910 | goto cleanup; | ||
911 | |||
912 | if (cg_create(memcg)) | ||
913 | goto cleanup; | ||
914 | |||
915 | while (bind_retries--) { | ||
916 | struct tcp_server_args args; | ||
917 | |||
918 | if (pipe(args.ctl)) | ||
919 | goto cleanup; | ||
920 | |||
921 | port = args.port = 1000 + rand() % 60000; | ||
922 | |||
923 | pid = cg_run_nowait(memcg, tcp_server, &args); | ||
924 | if (pid < 0) | ||
925 | goto cleanup; | ||
926 | |||
927 | close(args.ctl[1]); | ||
928 | if (read(args.ctl[0], &err, sizeof(err)) != sizeof(err)) | ||
929 | goto cleanup; | ||
930 | close(args.ctl[0]); | ||
931 | |||
932 | if (!err) | ||
933 | break; | ||
934 | if (err != EADDRINUSE) | ||
935 | goto cleanup; | ||
936 | |||
937 | waitpid(pid, NULL, 0); | ||
938 | } | ||
939 | |||
940 | if (err == EADDRINUSE) { | ||
941 | ret = KSFT_SKIP; | ||
942 | goto cleanup; | ||
943 | } | ||
944 | |||
945 | if (tcp_client(memcg, port) != KSFT_PASS) | ||
946 | goto cleanup; | ||
947 | |||
948 | waitpid(pid, &err, 0); | ||
949 | if (WEXITSTATUS(err)) | ||
950 | goto cleanup; | ||
951 | |||
952 | if (cg_read_long(memcg, "memory.current") < 0) | ||
953 | goto cleanup; | ||
954 | |||
955 | if (cg_read_key_long(memcg, "memory.stat", "sock ")) | ||
956 | goto cleanup; | ||
957 | |||
958 | ret = KSFT_PASS; | ||
959 | |||
960 | cleanup: | ||
961 | cg_destroy(memcg); | ||
962 | free(memcg); | ||
963 | |||
964 | return ret; | ||
965 | } | ||
966 | |||
967 | #define T(x) { x, #x } | ||
968 | struct memcg_test { | ||
969 | int (*fn)(const char *root); | ||
970 | const char *name; | ||
971 | } tests[] = { | ||
972 | T(test_memcg_subtree_control), | ||
973 | T(test_memcg_current), | ||
974 | T(test_memcg_min), | ||
975 | T(test_memcg_low), | ||
976 | T(test_memcg_high), | ||
977 | T(test_memcg_max), | ||
978 | T(test_memcg_oom_events), | ||
979 | T(test_memcg_swap_max), | ||
980 | T(test_memcg_sock), | ||
981 | }; | ||
982 | #undef T | ||
983 | |||
984 | int main(int argc, char **argv) | ||
985 | { | ||
986 | char root[PATH_MAX]; | ||
987 | int i, ret = EXIT_SUCCESS; | ||
988 | |||
989 | if (cg_find_unified_root(root, sizeof(root))) | ||
990 | ksft_exit_skip("cgroup v2 isn't mounted\n"); | ||
991 | |||
992 | /* | ||
993 | * Check that memory controller is available: | ||
994 | * memory is listed in cgroup.controllers | ||
995 | */ | ||
996 | if (cg_read_strstr(root, "cgroup.controllers", "memory")) | ||
997 | ksft_exit_skip("memory controller isn't available\n"); | ||
998 | |||
999 | for (i = 0; i < ARRAY_SIZE(tests); i++) { | ||
1000 | switch (tests[i].fn(root)) { | ||
1001 | case KSFT_PASS: | ||
1002 | ksft_test_result_pass("%s\n", tests[i].name); | ||
1003 | break; | ||
1004 | case KSFT_SKIP: | ||
1005 | ksft_test_result_skip("%s\n", tests[i].name); | ||
1006 | break; | ||
1007 | default: | ||
1008 | ret = EXIT_FAILURE; | ||
1009 | ksft_test_result_fail("%s\n", tests[i].name); | ||
1010 | break; | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | return ret; | ||
1015 | } | ||
diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh index f3a8933c1275..bab13dd025a6 100755 --- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh +++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh | |||
@@ -2,6 +2,8 @@ | |||
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | 3 | ||
4 | SYSFS= | 4 | SYSFS= |
5 | # Kselftest framework requirement - SKIP code is 4. | ||
6 | ksft_skip=4 | ||
5 | 7 | ||
6 | prerequisite() | 8 | prerequisite() |
7 | { | 9 | { |
@@ -9,7 +11,7 @@ prerequisite() | |||
9 | 11 | ||
10 | if [ $UID != 0 ]; then | 12 | if [ $UID != 0 ]; then |
11 | echo $msg must be run as root >&2 | 13 | echo $msg must be run as root >&2 |
12 | exit 0 | 14 | exit $ksft_skip |
13 | fi | 15 | fi |
14 | 16 | ||
15 | taskset -p 01 $$ | 17 | taskset -p 01 $$ |
@@ -18,12 +20,12 @@ prerequisite() | |||
18 | 20 | ||
19 | if [ ! -d "$SYSFS" ]; then | 21 | if [ ! -d "$SYSFS" ]; then |
20 | echo $msg sysfs is not mounted >&2 | 22 | echo $msg sysfs is not mounted >&2 |
21 | exit 0 | 23 | exit $ksft_skip |
22 | fi | 24 | fi |
23 | 25 | ||
24 | if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then | 26 | if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then |
25 | echo $msg cpu hotplug is not supported >&2 | 27 | echo $msg cpu hotplug is not supported >&2 |
26 | exit 0 | 28 | exit $ksft_skip |
27 | fi | 29 | fi |
28 | 30 | ||
29 | echo "CPU online/offline summary:" | 31 | echo "CPU online/offline summary:" |
@@ -32,7 +34,7 @@ prerequisite() | |||
32 | 34 | ||
33 | if [[ "$online_cpus" = "$online_max" ]]; then | 35 | if [[ "$online_cpus" = "$online_max" ]]; then |
34 | echo "$msg: since there is only one cpu: $online_cpus" | 36 | echo "$msg: since there is only one cpu: $online_cpus" |
35 | exit 0 | 37 | exit $ksft_skip |
36 | fi | 38 | fi |
37 | 39 | ||
38 | echo -e "\t Cpus in online state: $online_cpus" | 40 | echo -e "\t Cpus in online state: $online_cpus" |
@@ -237,12 +239,12 @@ prerequisite_extra() | |||
237 | 239 | ||
238 | if [ ! -d "$DEBUGFS" ]; then | 240 | if [ ! -d "$DEBUGFS" ]; then |
239 | echo $msg debugfs is not mounted >&2 | 241 | echo $msg debugfs is not mounted >&2 |
240 | exit 0 | 242 | exit $ksft_skip |
241 | fi | 243 | fi |
242 | 244 | ||
243 | if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then | 245 | if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then |
244 | echo $msg cpu-notifier-error-inject module is not available >&2 | 246 | echo $msg cpu-notifier-error-inject module is not available >&2 |
245 | exit 0 | 247 | exit $ksft_skip |
246 | fi | 248 | fi |
247 | } | 249 | } |
248 | 250 | ||
diff --git a/tools/testing/selftests/cpufreq/main.sh b/tools/testing/selftests/cpufreq/main.sh index d83922de9d89..31f8c9a76c5f 100755 --- a/tools/testing/selftests/cpufreq/main.sh +++ b/tools/testing/selftests/cpufreq/main.sh | |||
@@ -13,6 +13,9 @@ SYSFS= | |||
13 | CPUROOT= | 13 | CPUROOT= |
14 | CPUFREQROOT= | 14 | CPUFREQROOT= |
15 | 15 | ||
16 | # Kselftest framework requirement - SKIP code is 4. | ||
17 | ksft_skip=4 | ||
18 | |||
16 | helpme() | 19 | helpme() |
17 | { | 20 | { |
18 | printf "Usage: $0 [-h] [-todg args] | 21 | printf "Usage: $0 [-h] [-todg args] |
@@ -38,7 +41,7 @@ prerequisite() | |||
38 | 41 | ||
39 | if [ $UID != 0 ]; then | 42 | if [ $UID != 0 ]; then |
40 | echo $msg must be run as root >&2 | 43 | echo $msg must be run as root >&2 |
41 | exit 2 | 44 | exit $ksft_skip |
42 | fi | 45 | fi |
43 | 46 | ||
44 | taskset -p 01 $$ | 47 | taskset -p 01 $$ |
diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh index c6d5790575ae..a47029a799d2 100755 --- a/tools/testing/selftests/efivarfs/efivarfs.sh +++ b/tools/testing/selftests/efivarfs/efivarfs.sh | |||
@@ -4,18 +4,21 @@ | |||
4 | efivarfs_mount=/sys/firmware/efi/efivars | 4 | efivarfs_mount=/sys/firmware/efi/efivars |
5 | test_guid=210be57c-9849-4fc7-a635-e6382d1aec27 | 5 | test_guid=210be57c-9849-4fc7-a635-e6382d1aec27 |
6 | 6 | ||
7 | # Kselftest framework requirement - SKIP code is 4. | ||
8 | ksft_skip=4 | ||
9 | |||
7 | check_prereqs() | 10 | check_prereqs() |
8 | { | 11 | { |
9 | local msg="skip all tests:" | 12 | local msg="skip all tests:" |
10 | 13 | ||
11 | if [ $UID != 0 ]; then | 14 | if [ $UID != 0 ]; then |
12 | echo $msg must be run as root >&2 | 15 | echo $msg must be run as root >&2 |
13 | exit 0 | 16 | exit $ksft_skip |
14 | fi | 17 | fi |
15 | 18 | ||
16 | if ! grep -q "^\S\+ $efivarfs_mount efivarfs" /proc/mounts; then | 19 | if ! grep -q "^\S\+ $efivarfs_mount efivarfs" /proc/mounts; then |
17 | echo $msg efivarfs is not mounted on $efivarfs_mount >&2 | 20 | echo $msg efivarfs is not mounted on $efivarfs_mount >&2 |
18 | exit 0 | 21 | exit $ksft_skip |
19 | fi | 22 | fi |
20 | } | 23 | } |
21 | 24 | ||
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c index 67cd4597db2b..47cbf54d0801 100644 --- a/tools/testing/selftests/exec/execveat.c +++ b/tools/testing/selftests/exec/execveat.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <string.h> | 20 | #include <string.h> |
21 | #include <unistd.h> | 21 | #include <unistd.h> |
22 | 22 | ||
23 | #include "../kselftest.h" | ||
24 | |||
23 | static char longpath[2 * PATH_MAX] = ""; | 25 | static char longpath[2 * PATH_MAX] = ""; |
24 | static char *envp[] = { "IN_TEST=yes", NULL, NULL }; | 26 | static char *envp[] = { "IN_TEST=yes", NULL, NULL }; |
25 | static char *argv[] = { "execveat", "99", NULL }; | 27 | static char *argv[] = { "execveat", "99", NULL }; |
@@ -249,8 +251,8 @@ static int run_tests(void) | |||
249 | errno = 0; | 251 | errno = 0; |
250 | execveat_(-1, NULL, NULL, NULL, 0); | 252 | execveat_(-1, NULL, NULL, NULL, 0); |
251 | if (errno == ENOSYS) { | 253 | if (errno == ENOSYS) { |
252 | printf("[FAIL] ENOSYS calling execveat - no kernel support?\n"); | 254 | ksft_exit_skip( |
253 | return 1; | 255 | "ENOSYS calling execveat - no kernel support?\n"); |
254 | } | 256 | } |
255 | 257 | ||
256 | /* Change file position to confirm it doesn't affect anything */ | 258 | /* Change file position to confirm it doesn't affect anything */ |
diff --git a/tools/testing/selftests/filesystems/Makefile b/tools/testing/selftests/filesystems/Makefile index 5c7d7001ad37..129880fb42d3 100644 --- a/tools/testing/selftests/filesystems/Makefile +++ b/tools/testing/selftests/filesystems/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | 2 | ||
3 | CFLAGS += -I../../../../usr/include/ | ||
3 | TEST_GEN_PROGS := devpts_pts | 4 | TEST_GEN_PROGS := devpts_pts |
4 | TEST_GEN_PROGS_EXTENDED := dnotify_test | 5 | TEST_GEN_PROGS_EXTENDED := dnotify_test |
5 | 6 | ||
diff --git a/tools/testing/selftests/filesystems/devpts_pts.c b/tools/testing/selftests/filesystems/devpts_pts.c index b9055e974289..b1fc9b916ace 100644 --- a/tools/testing/selftests/filesystems/devpts_pts.c +++ b/tools/testing/selftests/filesystems/devpts_pts.c | |||
@@ -8,9 +8,10 @@ | |||
8 | #include <stdlib.h> | 8 | #include <stdlib.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | #include <unistd.h> | 10 | #include <unistd.h> |
11 | #include <sys/ioctl.h> | 11 | #include <asm/ioctls.h> |
12 | #include <sys/mount.h> | 12 | #include <sys/mount.h> |
13 | #include <sys/wait.h> | 13 | #include <sys/wait.h> |
14 | #include "../kselftest.h" | ||
14 | 15 | ||
15 | static bool terminal_dup2(int duplicate, int original) | 16 | static bool terminal_dup2(int duplicate, int original) |
16 | { | 17 | { |
@@ -125,10 +126,12 @@ static int do_tiocgptpeer(char *ptmx, char *expected_procfd_contents) | |||
125 | if (errno == EINVAL) { | 126 | if (errno == EINVAL) { |
126 | fprintf(stderr, "TIOCGPTPEER is not supported. " | 127 | fprintf(stderr, "TIOCGPTPEER is not supported. " |
127 | "Skipping test.\n"); | 128 | "Skipping test.\n"); |
128 | fret = EXIT_SUCCESS; | 129 | fret = KSFT_SKIP; |
130 | } else { | ||
131 | fprintf(stderr, | ||
132 | "Failed to perform TIOCGPTPEER ioctl\n"); | ||
133 | fret = EXIT_FAILURE; | ||
129 | } | 134 | } |
130 | |||
131 | fprintf(stderr, "Failed to perform TIOCGPTPEER ioctl\n"); | ||
132 | goto do_cleanup; | 135 | goto do_cleanup; |
133 | } | 136 | } |
134 | 137 | ||
@@ -279,9 +282,9 @@ int main(int argc, char *argv[]) | |||
279 | int ret; | 282 | int ret; |
280 | 283 | ||
281 | if (!isatty(STDIN_FILENO)) { | 284 | if (!isatty(STDIN_FILENO)) { |
282 | fprintf(stderr, "Standard input file desciptor is not attached " | 285 | fprintf(stderr, "Standard input file descriptor is not attached " |
283 | "to a terminal. Skipping test\n"); | 286 | "to a terminal. Skipping test\n"); |
284 | exit(EXIT_FAILURE); | 287 | exit(KSFT_SKIP); |
285 | } | 288 | } |
286 | 289 | ||
287 | ret = unshare(CLONE_NEWNS); | 290 | ret = unshare(CLONE_NEWNS); |
diff --git a/tools/testing/selftests/firmware/fw_fallback.sh b/tools/testing/selftests/firmware/fw_fallback.sh index 8e2e34a2ca69..70d18be46af5 100755 --- a/tools/testing/selftests/firmware/fw_fallback.sh +++ b/tools/testing/selftests/firmware/fw_fallback.sh | |||
@@ -74,7 +74,7 @@ load_fw_custom() | |||
74 | { | 74 | { |
75 | if [ ! -e "$DIR"/trigger_custom_fallback ]; then | 75 | if [ ! -e "$DIR"/trigger_custom_fallback ]; then |
76 | echo "$0: custom fallback trigger not present, ignoring test" >&2 | 76 | echo "$0: custom fallback trigger not present, ignoring test" >&2 |
77 | return 1 | 77 | exit $ksft_skip |
78 | fi | 78 | fi |
79 | 79 | ||
80 | local name="$1" | 80 | local name="$1" |
@@ -107,7 +107,7 @@ load_fw_custom_cancel() | |||
107 | { | 107 | { |
108 | if [ ! -e "$DIR"/trigger_custom_fallback ]; then | 108 | if [ ! -e "$DIR"/trigger_custom_fallback ]; then |
109 | echo "$0: canceling custom fallback trigger not present, ignoring test" >&2 | 109 | echo "$0: canceling custom fallback trigger not present, ignoring test" >&2 |
110 | return 1 | 110 | exit $ksft_skip |
111 | fi | 111 | fi |
112 | 112 | ||
113 | local name="$1" | 113 | local name="$1" |
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh index 6452d2129cd9..a4320c4b44dc 100755 --- a/tools/testing/selftests/firmware/fw_filesystem.sh +++ b/tools/testing/selftests/firmware/fw_filesystem.sh | |||
@@ -30,6 +30,7 @@ fi | |||
30 | 30 | ||
31 | if [ ! -e "$DIR"/trigger_async_request ]; then | 31 | if [ ! -e "$DIR"/trigger_async_request ]; then |
32 | echo "$0: empty filename: async trigger not present, ignoring test" >&2 | 32 | echo "$0: empty filename: async trigger not present, ignoring test" >&2 |
33 | exit $ksft_skip | ||
33 | else | 34 | else |
34 | if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then | 35 | if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then |
35 | echo "$0: empty filename should not succeed (async)" >&2 | 36 | echo "$0: empty filename should not succeed (async)" >&2 |
@@ -69,6 +70,7 @@ fi | |||
69 | # Try the asynchronous version too | 70 | # Try the asynchronous version too |
70 | if [ ! -e "$DIR"/trigger_async_request ]; then | 71 | if [ ! -e "$DIR"/trigger_async_request ]; then |
71 | echo "$0: firmware loading: async trigger not present, ignoring test" >&2 | 72 | echo "$0: firmware loading: async trigger not present, ignoring test" >&2 |
73 | exit $ksft_skip | ||
72 | else | 74 | else |
73 | if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then | 75 | if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then |
74 | echo "$0: could not trigger async request" >&2 | 76 | echo "$0: could not trigger async request" >&2 |
@@ -89,7 +91,7 @@ test_config_present() | |||
89 | { | 91 | { |
90 | if [ ! -f $DIR/reset ]; then | 92 | if [ ! -f $DIR/reset ]; then |
91 | echo "Configuration triggers not present, ignoring test" | 93 | echo "Configuration triggers not present, ignoring test" |
92 | exit 0 | 94 | exit $ksft_skip |
93 | fi | 95 | fi |
94 | } | 96 | } |
95 | 97 | ||
diff --git a/tools/testing/selftests/firmware/fw_lib.sh b/tools/testing/selftests/firmware/fw_lib.sh index 962d7f4ac627..6c5f1b2ffb74 100755 --- a/tools/testing/selftests/firmware/fw_lib.sh +++ b/tools/testing/selftests/firmware/fw_lib.sh | |||
@@ -9,11 +9,14 @@ DIR=/sys/devices/virtual/misc/test_firmware | |||
9 | PROC_CONFIG="/proc/config.gz" | 9 | PROC_CONFIG="/proc/config.gz" |
10 | TEST_DIR=$(dirname $0) | 10 | TEST_DIR=$(dirname $0) |
11 | 11 | ||
12 | # Kselftest framework requirement - SKIP code is 4. | ||
13 | ksft_skip=4 | ||
14 | |||
12 | print_reqs_exit() | 15 | print_reqs_exit() |
13 | { | 16 | { |
14 | echo "You must have the following enabled in your kernel:" >&2 | 17 | echo "You must have the following enabled in your kernel:" >&2 |
15 | cat $TEST_DIR/config >&2 | 18 | cat $TEST_DIR/config >&2 |
16 | exit 1 | 19 | exit $ksft_skip |
17 | } | 20 | } |
18 | 21 | ||
19 | test_modprobe() | 22 | test_modprobe() |
@@ -88,7 +91,7 @@ verify_reqs() | |||
88 | if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then | 91 | if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then |
89 | if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then | 92 | if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then |
90 | echo "usermode helper disabled so ignoring test" | 93 | echo "usermode helper disabled so ignoring test" |
91 | exit 0 | 94 | exit $ksft_skip |
92 | fi | 95 | fi |
93 | fi | 96 | fi |
94 | } | 97 | } |
diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile index 8497a376ef9d..12631f0076a1 100644 --- a/tools/testing/selftests/futex/Makefile +++ b/tools/testing/selftests/futex/Makefile | |||
@@ -17,14 +17,6 @@ all: | |||
17 | fi \ | 17 | fi \ |
18 | done | 18 | done |
19 | 19 | ||
20 | override define RUN_TESTS | ||
21 | @export KSFT_TAP_LEVEL=`echo 1`; | ||
22 | @echo "TAP version 13"; | ||
23 | @echo "selftests: futex"; | ||
24 | @echo "========================================"; | ||
25 | @cd $(OUTPUT); ./run.sh | ||
26 | endef | ||
27 | |||
28 | override define INSTALL_RULE | 20 | override define INSTALL_RULE |
29 | mkdir -p $(INSTALL_PATH) | 21 | mkdir -p $(INSTALL_PATH) |
30 | install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) | 22 | install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) |
@@ -36,10 +28,6 @@ override define INSTALL_RULE | |||
36 | done; | 28 | done; |
37 | endef | 29 | endef |
38 | 30 | ||
39 | override define EMIT_TESTS | ||
40 | echo "./run.sh" | ||
41 | endef | ||
42 | |||
43 | override define CLEAN | 31 | override define CLEAN |
44 | @for DIR in $(SUBDIRS); do \ | 32 | @for DIR in $(SUBDIRS); do \ |
45 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ | 33 | BUILD_TARGET=$(OUTPUT)/$$DIR; \ |
diff --git a/tools/testing/selftests/gpio/gpio-mockup.sh b/tools/testing/selftests/gpio/gpio-mockup.sh index 183fb932edbd..7f35b9880485 100755 --- a/tools/testing/selftests/gpio/gpio-mockup.sh +++ b/tools/testing/selftests/gpio/gpio-mockup.sh | |||
@@ -2,10 +2,11 @@ | |||
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | 3 | ||
4 | #exit status | 4 | #exit status |
5 | #1: run as non-root user | 5 | #1: Internal error |
6 | #2: sysfs/debugfs not mount | 6 | #2: sysfs/debugfs not mount |
7 | #3: insert module fail when gpio-mockup is a module. | 7 | #3: insert module fail when gpio-mockup is a module. |
8 | #4: other reason. | 8 | #4: Skip test including run as non-root user. |
9 | #5: other reason. | ||
9 | 10 | ||
10 | SYSFS= | 11 | SYSFS= |
11 | GPIO_SYSFS= | 12 | GPIO_SYSFS= |
@@ -15,6 +16,9 @@ GPIO_DEBUGFS= | |||
15 | dev_type= | 16 | dev_type= |
16 | module= | 17 | module= |
17 | 18 | ||
19 | # Kselftest framework requirement - SKIP code is 4. | ||
20 | ksft_skip=4 | ||
21 | |||
18 | usage() | 22 | usage() |
19 | { | 23 | { |
20 | echo "Usage:" | 24 | echo "Usage:" |
@@ -34,7 +38,7 @@ prerequisite() | |||
34 | msg="skip all tests:" | 38 | msg="skip all tests:" |
35 | if [ $UID != 0 ]; then | 39 | if [ $UID != 0 ]; then |
36 | echo $msg must be run as root >&2 | 40 | echo $msg must be run as root >&2 |
37 | exit 1 | 41 | exit $ksft_skip |
38 | fi | 42 | fi |
39 | SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` | 43 | SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` |
40 | if [ ! -d "$SYSFS" ]; then | 44 | if [ ! -d "$SYSFS" ]; then |
@@ -73,7 +77,7 @@ remove_module() | |||
73 | die() | 77 | die() |
74 | { | 78 | { |
75 | remove_module | 79 | remove_module |
76 | exit 4 | 80 | exit 5 |
77 | } | 81 | } |
78 | 82 | ||
79 | test_chips() | 83 | test_chips() |
diff --git a/tools/testing/selftests/intel_pstate/aperf.c b/tools/testing/selftests/intel_pstate/aperf.c index d21edea9c560..f6cd03a87493 100644 --- a/tools/testing/selftests/intel_pstate/aperf.c +++ b/tools/testing/selftests/intel_pstate/aperf.c | |||
@@ -9,6 +9,8 @@ | |||
9 | #include <sys/timeb.h> | 9 | #include <sys/timeb.h> |
10 | #include <sched.h> | 10 | #include <sched.h> |
11 | #include <errno.h> | 11 | #include <errno.h> |
12 | #include <string.h> | ||
13 | #include "../kselftest.h" | ||
12 | 14 | ||
13 | void usage(char *name) { | 15 | void usage(char *name) { |
14 | printf ("Usage: %s cpunum\n", name); | 16 | printf ("Usage: %s cpunum\n", name); |
@@ -41,8 +43,8 @@ int main(int argc, char **argv) { | |||
41 | fd = open(msr_file_name, O_RDONLY); | 43 | fd = open(msr_file_name, O_RDONLY); |
42 | 44 | ||
43 | if (fd == -1) { | 45 | if (fd == -1) { |
44 | perror("Failed to open"); | 46 | printf("/dev/cpu/%d/msr: %s\n", cpu, strerror(errno)); |
45 | return 1; | 47 | return KSFT_SKIP; |
46 | } | 48 | } |
47 | 49 | ||
48 | CPU_ZERO(&cpuset); | 50 | CPU_ZERO(&cpuset); |
diff --git a/tools/testing/selftests/intel_pstate/run.sh b/tools/testing/selftests/intel_pstate/run.sh index c670359becc6..e7008f614ad7 100755 --- a/tools/testing/selftests/intel_pstate/run.sh +++ b/tools/testing/selftests/intel_pstate/run.sh | |||
@@ -30,9 +30,18 @@ | |||
30 | 30 | ||
31 | EVALUATE_ONLY=0 | 31 | EVALUATE_ONLY=0 |
32 | 32 | ||
33 | # Kselftest framework requirement - SKIP code is 4. | ||
34 | ksft_skip=4 | ||
35 | |||
33 | if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then | 36 | if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then |
34 | echo "$0 # Skipped: Test can only run on x86 architectures." | 37 | echo "$0 # Skipped: Test can only run on x86 architectures." |
35 | exit 0 | 38 | exit $ksft_skip |
39 | fi | ||
40 | |||
41 | msg="skip all tests:" | ||
42 | if [ $UID != 0 ] && [ $EVALUATE_ONLY == 0 ]; then | ||
43 | echo $msg please run this as root >&2 | ||
44 | exit $ksft_skip | ||
36 | fi | 45 | fi |
37 | 46 | ||
38 | max_cpus=$(($(nproc)-1)) | 47 | max_cpus=$(($(nproc)-1)) |
@@ -48,11 +57,12 @@ function run_test () { | |||
48 | 57 | ||
49 | echo "sleeping for 5 seconds" | 58 | echo "sleeping for 5 seconds" |
50 | sleep 5 | 59 | sleep 5 |
51 | num_freqs=$(cat /proc/cpuinfo | grep MHz | sort -u | wc -l) | 60 | grep MHz /proc/cpuinfo | sort -u > /tmp/result.freqs |
52 | if [ $num_freqs -le 2 ]; then | 61 | num_freqs=$(wc -l /tmp/result.freqs | awk ' { print $1 } ') |
53 | cat /proc/cpuinfo | grep MHz | sort -u | tail -1 > /tmp/result.$1 | 62 | if [ $num_freqs -ge 2 ]; then |
63 | tail -n 1 /tmp/result.freqs > /tmp/result.$1 | ||
54 | else | 64 | else |
55 | cat /proc/cpuinfo | grep MHz | sort -u > /tmp/result.$1 | 65 | cp /tmp/result.freqs /tmp/result.$1 |
56 | fi | 66 | fi |
57 | ./msr 0 >> /tmp/result.$1 | 67 | ./msr 0 >> /tmp/result.$1 |
58 | 68 | ||
@@ -82,32 +92,37 @@ _max_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $2 } ') | |||
82 | max_freq=$(($_max_freq / 1000)) | 92 | max_freq=$(($_max_freq / 1000)) |
83 | 93 | ||
84 | 94 | ||
85 | for freq in `seq $max_freq -100 $min_freq` | 95 | [ $EVALUATE_ONLY -eq 0 ] && for freq in `seq $max_freq -100 $min_freq` |
86 | do | 96 | do |
87 | echo "Setting maximum frequency to $freq" | 97 | echo "Setting maximum frequency to $freq" |
88 | cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null | 98 | cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null |
89 | [ $EVALUATE_ONLY -eq 0 ] && run_test $freq | 99 | run_test $freq |
90 | done | 100 | done |
91 | 101 | ||
92 | echo "==============================================================================" | 102 | [ $EVALUATE_ONLY -eq 0 ] && cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null |
93 | 103 | ||
104 | echo "========================================================================" | ||
94 | echo "The marketing frequency of the cpu is $mkt_freq MHz" | 105 | echo "The marketing frequency of the cpu is $mkt_freq MHz" |
95 | echo "The maximum frequency of the cpu is $max_freq MHz" | 106 | echo "The maximum frequency of the cpu is $max_freq MHz" |
96 | echo "The minimum frequency of the cpu is $min_freq MHz" | 107 | echo "The minimum frequency of the cpu is $min_freq MHz" |
97 | 108 | ||
98 | cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null | ||
99 | |||
100 | # make a pretty table | 109 | # make a pretty table |
101 | echo "Target Actual Difference MSR(0x199) max_perf_pct" | 110 | echo "Target Actual Difference MSR(0x199) max_perf_pct" | tr " " "\n" > /tmp/result.tab |
102 | for freq in `seq $max_freq -100 $min_freq` | 111 | for freq in `seq $max_freq -100 $min_freq` |
103 | do | 112 | do |
104 | result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ') | 113 | result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ') |
105 | msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ') | 114 | msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ') |
106 | max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' ) | 115 | max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' ) |
107 | if [ $result_freq -eq $freq ]; then | 116 | cat >> /tmp/result.tab << EOF |
108 | echo " $freq $result_freq 0 $msr $(($max_perf_pct*3300))" | 117 | $freq |
109 | else | 118 | $result_freq |
110 | echo " $freq $result_freq $(($result_freq-$freq)) $msr $(($max_perf_pct*$max_freq))" | 119 | $((result_freq - freq)) |
111 | fi | 120 | $msr |
121 | $((max_perf_pct * max_freq)) | ||
122 | EOF | ||
112 | done | 123 | done |
124 | |||
125 | # print the table | ||
126 | pr -aTt -5 < /tmp/result.tab | ||
127 | |||
113 | exit 0 | 128 | exit 0 |
diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c index ee9382bdfadc..dac927e82336 100644 --- a/tools/testing/selftests/ipc/msgque.c +++ b/tools/testing/selftests/ipc/msgque.c | |||
@@ -196,10 +196,9 @@ int main(int argc, char **argv) | |||
196 | int msg, pid, err; | 196 | int msg, pid, err; |
197 | struct msgque_data msgque; | 197 | struct msgque_data msgque; |
198 | 198 | ||
199 | if (getuid() != 0) { | 199 | if (getuid() != 0) |
200 | printf("Please run the test as root - Exiting.\n"); | 200 | return ksft_exit_skip( |
201 | return ksft_exit_fail(); | 201 | "Please run the test as root - Exiting.\n"); |
202 | } | ||
203 | 202 | ||
204 | msgque.key = ftok(argv[0], 822155650); | 203 | msgque.key = ftok(argv[0], 822155650); |
205 | if (msgque.key == -1) { | 204 | if (msgque.key == -1) { |
diff --git a/tools/testing/selftests/kmod/kmod.sh b/tools/testing/selftests/kmod/kmod.sh index 7956ea3be667..0a76314b4414 100755 --- a/tools/testing/selftests/kmod/kmod.sh +++ b/tools/testing/selftests/kmod/kmod.sh | |||
@@ -62,13 +62,16 @@ ALL_TESTS="$ALL_TESTS 0007:5:1" | |||
62 | ALL_TESTS="$ALL_TESTS 0008:150:1" | 62 | ALL_TESTS="$ALL_TESTS 0008:150:1" |
63 | ALL_TESTS="$ALL_TESTS 0009:150:1" | 63 | ALL_TESTS="$ALL_TESTS 0009:150:1" |
64 | 64 | ||
65 | # Kselftest framework requirement - SKIP code is 4. | ||
66 | ksft_skip=4 | ||
67 | |||
65 | test_modprobe() | 68 | test_modprobe() |
66 | { | 69 | { |
67 | if [ ! -d $DIR ]; then | 70 | if [ ! -d $DIR ]; then |
68 | echo "$0: $DIR not present" >&2 | 71 | echo "$0: $DIR not present" >&2 |
69 | echo "You must have the following enabled in your kernel:" >&2 | 72 | echo "You must have the following enabled in your kernel:" >&2 |
70 | cat $TEST_DIR/config >&2 | 73 | cat $TEST_DIR/config >&2 |
71 | exit 1 | 74 | exit $ksft_skip |
72 | fi | 75 | fi |
73 | } | 76 | } |
74 | 77 | ||
@@ -105,12 +108,12 @@ test_reqs() | |||
105 | { | 108 | { |
106 | if ! which modprobe 2> /dev/null > /dev/null; then | 109 | if ! which modprobe 2> /dev/null > /dev/null; then |
107 | echo "$0: You need modprobe installed" >&2 | 110 | echo "$0: You need modprobe installed" >&2 |
108 | exit 1 | 111 | exit $ksft_skip |
109 | fi | 112 | fi |
110 | 113 | ||
111 | if ! which kmod 2> /dev/null > /dev/null; then | 114 | if ! which kmod 2> /dev/null > /dev/null; then |
112 | echo "$0: You need kmod installed" >&2 | 115 | echo "$0: You need kmod installed" >&2 |
113 | exit 1 | 116 | exit $ksft_skip |
114 | fi | 117 | fi |
115 | 118 | ||
116 | # kmod 19 has a bad bug where it returns 0 when modprobe | 119 | # kmod 19 has a bad bug where it returns 0 when modprobe |
@@ -124,13 +127,13 @@ test_reqs() | |||
124 | echo "$0: You need at least kmod 20" >&2 | 127 | echo "$0: You need at least kmod 20" >&2 |
125 | echo "kmod <= 19 is buggy, for details see:" >&2 | 128 | echo "kmod <= 19 is buggy, for details see:" >&2 |
126 | echo "http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2 | 129 | echo "http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2 |
127 | exit 1 | 130 | exit $ksft_skip |
128 | fi | 131 | fi |
129 | 132 | ||
130 | uid=$(id -u) | 133 | uid=$(id -u) |
131 | if [ $uid -ne 0 ]; then | 134 | if [ $uid -ne 0 ]; then |
132 | echo $msg must be run as root >&2 | 135 | echo $msg must be run as root >&2 |
133 | exit 0 | 136 | exit $ksft_skip |
134 | fi | 137 | fi |
135 | } | 138 | } |
136 | 139 | ||
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index 1b9d8ecdebce..15e6b75fc3a5 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #define KSFT_XFAIL 2 | 20 | #define KSFT_XFAIL 2 |
21 | #define KSFT_XPASS 3 | 21 | #define KSFT_XPASS 3 |
22 | /* Treat skip as pass */ | 22 | /* Treat skip as pass */ |
23 | #define KSFT_SKIP KSFT_PASS | 23 | #define KSFT_SKIP 4 |
24 | 24 | ||
25 | /* counters */ | 25 | /* counters */ |
26 | struct ksft_count { | 26 | struct ksft_count { |
diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore new file mode 100644 index 000000000000..63fc1ab9248f --- /dev/null +++ b/tools/testing/selftests/kvm/.gitignore | |||
@@ -0,0 +1,3 @@ | |||
1 | set_sregs_test | ||
2 | sync_regs_test | ||
3 | vmx_tsc_adjust_test | ||
diff --git a/tools/testing/selftests/kvm/lib/assert.c b/tools/testing/selftests/kvm/lib/assert.c index c9f5b7d4ce38..cd01144d27c8 100644 --- a/tools/testing/selftests/kvm/lib/assert.c +++ b/tools/testing/selftests/kvm/lib/assert.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <execinfo.h> | 13 | #include <execinfo.h> |
14 | #include <sys/syscall.h> | 14 | #include <sys/syscall.h> |
15 | 15 | ||
16 | #include "../../kselftest.h" | ||
17 | |||
16 | /* Dumps the current stack trace to stderr. */ | 18 | /* Dumps the current stack trace to stderr. */ |
17 | static void __attribute__((noinline)) test_dump_stack(void); | 19 | static void __attribute__((noinline)) test_dump_stack(void); |
18 | static void test_dump_stack(void) | 20 | static void test_dump_stack(void) |
@@ -70,8 +72,9 @@ test_assert(bool exp, const char *exp_str, | |||
70 | 72 | ||
71 | fprintf(stderr, "==== Test Assertion Failure ====\n" | 73 | fprintf(stderr, "==== Test Assertion Failure ====\n" |
72 | " %s:%u: %s\n" | 74 | " %s:%u: %s\n" |
73 | " pid=%d tid=%d\n", | 75 | " pid=%d tid=%d - %s\n", |
74 | file, line, exp_str, getpid(), gettid()); | 76 | file, line, exp_str, getpid(), gettid(), |
77 | strerror(errno)); | ||
75 | test_dump_stack(); | 78 | test_dump_stack(); |
76 | if (fmt) { | 79 | if (fmt) { |
77 | fputs(" ", stderr); | 80 | fputs(" ", stderr); |
@@ -80,6 +83,8 @@ test_assert(bool exp, const char *exp_str, | |||
80 | } | 83 | } |
81 | va_end(ap); | 84 | va_end(ap); |
82 | 85 | ||
86 | if (errno == EACCES) | ||
87 | ksft_exit_skip("Access denied - Exiting.\n"); | ||
83 | exit(254); | 88 | exit(254); |
84 | } | 89 | } |
85 | 90 | ||
diff --git a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c index aaa633263b2c..d7cb7944a42e 100644 --- a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c +++ b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include <sys/ioctl.h> | 29 | #include <sys/ioctl.h> |
30 | 30 | ||
31 | #include "../kselftest.h" | ||
32 | |||
31 | #ifndef MSR_IA32_TSC_ADJUST | 33 | #ifndef MSR_IA32_TSC_ADJUST |
32 | #define MSR_IA32_TSC_ADJUST 0x3b | 34 | #define MSR_IA32_TSC_ADJUST 0x3b |
33 | #endif | 35 | #endif |
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index c1b1a4dc6a96..6466294366dc 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk | |||
@@ -19,25 +19,43 @@ TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES)) | |||
19 | all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) | 19 | all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) |
20 | 20 | ||
21 | .ONESHELL: | 21 | .ONESHELL: |
22 | define RUN_TEST_PRINT_RESULT | ||
23 | TEST_HDR_MSG="selftests: "`basename $$PWD`:" $$BASENAME_TEST"; \ | ||
24 | echo $$TEST_HDR_MSG; \ | ||
25 | echo "========================================"; \ | ||
26 | if [ ! -x $$TEST ]; then \ | ||
27 | echo "$$TEST_HDR_MSG: Warning: file $$BASENAME_TEST is not executable, correct this.";\ | ||
28 | echo "not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]"; \ | ||
29 | else \ | ||
30 | cd `dirname $$TEST` > /dev/null; \ | ||
31 | if [ "X$(summary)" != "X" ]; then \ | ||
32 | (./$$BASENAME_TEST > /tmp/$$BASENAME_TEST 2>&1 && \ | ||
33 | echo "ok 1..$$test_num $$TEST_HDR_MSG [PASS]") || \ | ||
34 | (if [ $$? -eq $$skip ]; then \ | ||
35 | echo "not ok 1..$$test_num $$TEST_HDR_MSG [SKIP]"; \ | ||
36 | else echo "not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]"; \ | ||
37 | fi;) \ | ||
38 | else \ | ||
39 | (./$$BASENAME_TEST && \ | ||
40 | echo "ok 1..$$test_num $$TEST_HDR_MSG [PASS]") || \ | ||
41 | (if [ $$? -eq $$skip ]; then \ | ||
42 | echo "not ok 1..$$test_num $$TEST_HDR_MSG [SKIP]"; \ | ||
43 | else echo "not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]"; \ | ||
44 | fi;) \ | ||
45 | fi; \ | ||
46 | cd - > /dev/null; \ | ||
47 | fi; | ||
48 | endef | ||
49 | |||
22 | define RUN_TESTS | 50 | define RUN_TESTS |
23 | @export KSFT_TAP_LEVEL=`echo 1`; \ | 51 | @export KSFT_TAP_LEVEL=`echo 1`; \ |
24 | test_num=`echo 0`; \ | 52 | test_num=`echo 0`; \ |
53 | skip=`echo 4`; \ | ||
25 | echo "TAP version 13"; \ | 54 | echo "TAP version 13"; \ |
26 | for TEST in $(1); do \ | 55 | for TEST in $(1); do \ |
27 | BASENAME_TEST=`basename $$TEST`; \ | 56 | BASENAME_TEST=`basename $$TEST`; \ |
28 | test_num=`echo $$test_num+1 | bc`; \ | 57 | test_num=`echo $$test_num+1 | bc`; \ |
29 | echo "selftests: $$BASENAME_TEST"; \ | 58 | $(call RUN_TEST_PRINT_RESULT,$(TEST),$(BASENAME_TEST),$(test_num),$(skip)) \ |
30 | echo "========================================"; \ | ||
31 | if [ ! -x $$TEST ]; then \ | ||
32 | echo "selftests: Warning: file $$BASENAME_TEST is not executable, correct this.";\ | ||
33 | echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; \ | ||
34 | else \ | ||
35 | if [ "X$(summary)" != "X" ]; then \ | ||
36 | cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST > /tmp/$$BASENAME_TEST 2>&1 && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\ | ||
37 | else \ | ||
38 | cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\ | ||
39 | fi; \ | ||
40 | fi; \ | ||
41 | done; | 59 | done; |
42 | endef | 60 | endef |
43 | 61 | ||
@@ -76,9 +94,18 @@ else | |||
76 | endif | 94 | endif |
77 | 95 | ||
78 | define EMIT_TESTS | 96 | define EMIT_TESTS |
79 | @for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \ | 97 | @test_num=`echo 0`; \ |
98 | for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \ | ||
80 | BASENAME_TEST=`basename $$TEST`; \ | 99 | BASENAME_TEST=`basename $$TEST`; \ |
81 | echo "(./$$BASENAME_TEST >> \$$OUTPUT 2>&1 && echo \"selftests: $$BASENAME_TEST [PASS]\") || echo \"selftests: $$BASENAME_TEST [FAIL]\""; \ | 100 | test_num=`echo $$test_num+1 | bc`; \ |
101 | TEST_HDR_MSG="selftests: "`basename $$PWD`:" $$BASENAME_TEST"; \ | ||
102 | echo "echo $$TEST_HDR_MSG"; \ | ||
103 | if [ ! -x $$TEST ]; then \ | ||
104 | echo "echo \"$$TEST_HDR_MSG: Warning: file $$BASENAME_TEST is not executable, correct this.\""; \ | ||
105 | echo "echo \"not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]\""; \ | ||
106 | else | ||
107 | echo "(./$$BASENAME_TEST >> \$$OUTPUT 2>&1 && echo \"ok 1..$$test_num $$TEST_HDR_MSG [PASS]\") || (if [ \$$? -eq \$$skip ]; then echo \"not ok 1..$$test_num $$TEST_HDR_MSG [SKIP]\"; else echo \"not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]\"; fi;)"; \ | ||
108 | fi; \ | ||
82 | done; | 109 | done; |
83 | endef | 110 | endef |
84 | 111 | ||
diff --git a/tools/testing/selftests/lib/Makefile b/tools/testing/selftests/lib/Makefile index 08360060ab14..70d5711e3ac8 100644 --- a/tools/testing/selftests/lib/Makefile +++ b/tools/testing/selftests/lib/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" | 3 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" |
4 | all: | 4 | all: |
5 | 5 | ||
6 | TEST_PROGS := printf.sh bitmap.sh | 6 | TEST_PROGS := printf.sh bitmap.sh prime_numbers.sh |
7 | 7 | ||
8 | include ../lib.mk | 8 | include ../lib.mk |
diff --git a/tools/testing/selftests/lib/bitmap.sh b/tools/testing/selftests/lib/bitmap.sh index 4dee4d2a8bbe..5a90006d1aea 100755 --- a/tools/testing/selftests/lib/bitmap.sh +++ b/tools/testing/selftests/lib/bitmap.sh | |||
@@ -1,9 +1,13 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | |||
4 | # Kselftest framework requirement - SKIP code is 4. | ||
5 | ksft_skip=4 | ||
6 | |||
3 | # Runs bitmap infrastructure tests using test_bitmap kernel module | 7 | # Runs bitmap infrastructure tests using test_bitmap kernel module |
4 | if ! /sbin/modprobe -q -n test_bitmap; then | 8 | if ! /sbin/modprobe -q -n test_bitmap; then |
5 | echo "bitmap: [SKIP]" | 9 | echo "bitmap: module test_bitmap is not found [SKIP]" |
6 | exit 77 | 10 | exit $ksft_skip |
7 | fi | 11 | fi |
8 | 12 | ||
9 | if /sbin/modprobe -q test_bitmap; then | 13 | if /sbin/modprobe -q test_bitmap; then |
diff --git a/tools/testing/selftests/lib/prime_numbers.sh b/tools/testing/selftests/lib/prime_numbers.sh index b363994e5e11..78e7483c8d60 100755 --- a/tools/testing/selftests/lib/prime_numbers.sh +++ b/tools/testing/selftests/lib/prime_numbers.sh | |||
@@ -2,9 +2,12 @@ | |||
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | # Checks fast/slow prime_number generation for inconsistencies | 3 | # Checks fast/slow prime_number generation for inconsistencies |
4 | 4 | ||
5 | if ! /sbin/modprobe -q -r prime_numbers; then | 5 | # Kselftest framework requirement - SKIP code is 4. |
6 | echo "prime_numbers: [SKIP]" | 6 | ksft_skip=4 |
7 | exit 77 | 7 | |
8 | if ! /sbin/modprobe -q -n prime_numbers; then | ||
9 | echo "prime_numbers: module prime_numbers is not found [SKIP]" | ||
10 | exit $ksft_skip | ||
8 | fi | 11 | fi |
9 | 12 | ||
10 | if /sbin/modprobe -q prime_numbers selftest=65536; then | 13 | if /sbin/modprobe -q prime_numbers selftest=65536; then |
diff --git a/tools/testing/selftests/lib/printf.sh b/tools/testing/selftests/lib/printf.sh index 0c37377fd7d4..45a23e2d64ad 100755 --- a/tools/testing/selftests/lib/printf.sh +++ b/tools/testing/selftests/lib/printf.sh | |||
@@ -1,9 +1,13 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | # Runs printf infrastructure using test_printf kernel module | 3 | # Runs printf infrastructure using test_printf kernel module |
4 | |||
5 | # Kselftest framework requirement - SKIP code is 4. | ||
6 | ksft_skip=4 | ||
7 | |||
4 | if ! /sbin/modprobe -q -n test_printf; then | 8 | if ! /sbin/modprobe -q -n test_printf; then |
5 | echo "printf: [SKIP]" | 9 | echo "printf: module test_printf is not found [SKIP]" |
6 | exit 77 | 10 | exit $ksft_skip |
7 | fi | 11 | fi |
8 | 12 | ||
9 | if /sbin/modprobe -q test_printf; then | 13 | if /sbin/modprobe -q test_printf; then |
diff --git a/tools/testing/selftests/locking/Makefile b/tools/testing/selftests/locking/Makefile new file mode 100644 index 000000000000..6e7761ab3536 --- /dev/null +++ b/tools/testing/selftests/locking/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | # | ||
3 | # Makefile for locking/ww_mutx selftests | ||
4 | |||
5 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" | ||
6 | all: | ||
7 | |||
8 | TEST_PROGS := ww_mutex.sh | ||
9 | |||
10 | include ../lib.mk | ||
diff --git a/tools/testing/selftests/locking/ww_mutex.sh b/tools/testing/selftests/locking/ww_mutex.sh index 2c3d6b1878c2..91e4ac7566af 100644..100755 --- a/tools/testing/selftests/locking/ww_mutex.sh +++ b/tools/testing/selftests/locking/ww_mutex.sh | |||
@@ -1,6 +1,14 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | |||
4 | # Kselftest framework requirement - SKIP code is 4. | ||
5 | ksft_skip=4 | ||
6 | |||
3 | # Runs API tests for struct ww_mutex (Wait/Wound mutexes) | 7 | # Runs API tests for struct ww_mutex (Wait/Wound mutexes) |
8 | if ! /sbin/modprobe -q -n test-ww_mutex; then | ||
9 | echo "ww_mutex: module test-ww_mutex is not found [SKIP]" | ||
10 | exit $ksft_skip | ||
11 | fi | ||
4 | 12 | ||
5 | if /sbin/modprobe -q test-ww_mutex; then | 13 | if /sbin/modprobe -q test-ww_mutex; then |
6 | /sbin/modprobe -q -r test-ww_mutex | 14 | /sbin/modprobe -q -r test-ww_mutex |
diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile index c82cec2497de..60826d7d37d4 100644 --- a/tools/testing/selftests/media_tests/Makefile +++ b/tools/testing/selftests/media_tests/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | # | ||
3 | CFLAGS += -I../ -I../../../../usr/include/ | ||
2 | TEST_GEN_PROGS := media_device_test media_device_open video_device_test | 4 | TEST_GEN_PROGS := media_device_test media_device_open video_device_test |
3 | all: $(TEST_GEN_PROGS) | ||
4 | 5 | ||
5 | include ../lib.mk | 6 | include ../lib.mk |
diff --git a/tools/testing/selftests/media_tests/media_device_open.c b/tools/testing/selftests/media_tests/media_device_open.c index a5ce5434bafd..93183a37b133 100644 --- a/tools/testing/selftests/media_tests/media_device_open.c +++ b/tools/testing/selftests/media_tests/media_device_open.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <sys/stat.h> | 34 | #include <sys/stat.h> |
35 | #include <linux/media.h> | 35 | #include <linux/media.h> |
36 | 36 | ||
37 | #include "../kselftest.h" | ||
38 | |||
37 | int main(int argc, char **argv) | 39 | int main(int argc, char **argv) |
38 | { | 40 | { |
39 | int opt; | 41 | int opt; |
@@ -61,10 +63,8 @@ int main(int argc, char **argv) | |||
61 | } | 63 | } |
62 | } | 64 | } |
63 | 65 | ||
64 | if (getuid() != 0) { | 66 | if (getuid() != 0) |
65 | printf("Please run the test as root - Exiting.\n"); | 67 | ksft_exit_skip("Please run the test as root - Exiting.\n"); |
66 | exit(-1); | ||
67 | } | ||
68 | 68 | ||
69 | /* Open Media device and keep it open */ | 69 | /* Open Media device and keep it open */ |
70 | fd = open(media_device, O_RDWR); | 70 | fd = open(media_device, O_RDWR); |
diff --git a/tools/testing/selftests/media_tests/media_device_test.c b/tools/testing/selftests/media_tests/media_device_test.c index 421a367e4bb3..4b9953359e40 100644 --- a/tools/testing/selftests/media_tests/media_device_test.c +++ b/tools/testing/selftests/media_tests/media_device_test.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <time.h> | 39 | #include <time.h> |
40 | #include <linux/media.h> | 40 | #include <linux/media.h> |
41 | 41 | ||
42 | #include "../kselftest.h" | ||
43 | |||
42 | int main(int argc, char **argv) | 44 | int main(int argc, char **argv) |
43 | { | 45 | { |
44 | int opt; | 46 | int opt; |
@@ -66,10 +68,8 @@ int main(int argc, char **argv) | |||
66 | } | 68 | } |
67 | } | 69 | } |
68 | 70 | ||
69 | if (getuid() != 0) { | 71 | if (getuid() != 0) |
70 | printf("Please run the test as root - Exiting.\n"); | 72 | ksft_exit_skip("Please run the test as root - Exiting.\n"); |
71 | exit(-1); | ||
72 | } | ||
73 | 73 | ||
74 | /* Generate random number of interations */ | 74 | /* Generate random number of interations */ |
75 | srand((unsigned int) time(NULL)); | 75 | srand((unsigned int) time(NULL)); |
@@ -88,7 +88,7 @@ int main(int argc, char **argv) | |||
88 | "other Oops in the dmesg. Enable KaSan kernel\n" | 88 | "other Oops in the dmesg. Enable KaSan kernel\n" |
89 | "config option for use-after-free error detection.\n\n"); | 89 | "config option for use-after-free error detection.\n\n"); |
90 | 90 | ||
91 | printf("Running test for %d iternations\n", count); | 91 | printf("Running test for %d iterations\n", count); |
92 | 92 | ||
93 | while (count > 0) { | 93 | while (count > 0) { |
94 | ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); | 94 | ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); |
diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c index 22bffd55a523..6793f8ecc8e7 100644 --- a/tools/testing/selftests/membarrier/membarrier_test.c +++ b/tools/testing/selftests/membarrier/membarrier_test.c | |||
@@ -293,10 +293,9 @@ static int test_membarrier_query(void) | |||
293 | } | 293 | } |
294 | ksft_exit_fail_msg("sys_membarrier() failed\n"); | 294 | ksft_exit_fail_msg("sys_membarrier() failed\n"); |
295 | } | 295 | } |
296 | if (!(ret & MEMBARRIER_CMD_GLOBAL)) { | 296 | if (!(ret & MEMBARRIER_CMD_GLOBAL)) |
297 | ksft_test_result_fail("sys_membarrier() CMD_GLOBAL query failed\n"); | 297 | ksft_exit_skip( |
298 | ksft_exit_fail_msg("sys_membarrier is not supported.\n"); | 298 | "sys_membarrier unsupported: CMD_GLOBAL not found.\n"); |
299 | } | ||
300 | 299 | ||
301 | ksft_test_result_pass("sys_membarrier available\n"); | 300 | ksft_test_result_pass("sys_membarrier available\n"); |
302 | return 0; | 301 | return 0; |
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 0862e6f47a38..53a848109f7b 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile | |||
@@ -4,9 +4,9 @@ CFLAGS += -I../../../../include/uapi/ | |||
4 | CFLAGS += -I../../../../include/ | 4 | CFLAGS += -I../../../../include/ |
5 | CFLAGS += -I../../../../usr/include/ | 5 | CFLAGS += -I../../../../usr/include/ |
6 | 6 | ||
7 | TEST_PROGS := run_tests.sh | 7 | TEST_GEN_PROGS := memfd_test |
8 | TEST_FILES := run_fuse_test.sh | 8 | TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh |
9 | TEST_GEN_FILES := memfd_test fuse_mnt fuse_test | 9 | TEST_GEN_FILES := fuse_mnt fuse_test |
10 | 10 | ||
11 | fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) | 11 | fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) |
12 | 12 | ||
diff --git a/tools/testing/selftests/memfd/run_tests.sh b/tools/testing/selftests/memfd/run_hugetlbfs_test.sh index c2d41ed81b24..fb633eeb0290 100755 --- a/tools/testing/selftests/memfd/run_tests.sh +++ b/tools/testing/selftests/memfd/run_hugetlbfs_test.sh | |||
@@ -1,11 +1,8 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # please run as root | 2 | # please run as root |
3 | 3 | ||
4 | # | 4 | # Kselftest framework requirement - SKIP code is 4. |
5 | # Normal tests requiring no special resources | 5 | ksft_skip=4 |
6 | # | ||
7 | ./run_fuse_test.sh | ||
8 | ./memfd_test | ||
9 | 6 | ||
10 | # | 7 | # |
11 | # To test memfd_create with hugetlbfs, there needs to be hpages_test | 8 | # To test memfd_create with hugetlbfs, there needs to be hpages_test |
@@ -29,12 +26,13 @@ if [ -n "$freepgs" ] && [ $freepgs -lt $hpages_test ]; then | |||
29 | nr_hugepgs=`cat /proc/sys/vm/nr_hugepages` | 26 | nr_hugepgs=`cat /proc/sys/vm/nr_hugepages` |
30 | hpages_needed=`expr $hpages_test - $freepgs` | 27 | hpages_needed=`expr $hpages_test - $freepgs` |
31 | 28 | ||
29 | if [ $UID != 0 ]; then | ||
30 | echo "Please run memfd with hugetlbfs test as root" | ||
31 | exit $ksft_skip | ||
32 | fi | ||
33 | |||
32 | echo 3 > /proc/sys/vm/drop_caches | 34 | echo 3 > /proc/sys/vm/drop_caches |
33 | echo $(( $hpages_needed + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages | 35 | echo $(( $hpages_needed + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages |
34 | if [ $? -ne 0 ]; then | ||
35 | echo "Please run this test as root" | ||
36 | exit 1 | ||
37 | fi | ||
38 | while read name size unit; do | 36 | while read name size unit; do |
39 | if [ "$name" = "HugePages_Free:" ]; then | 37 | if [ "$name" = "HugePages_Free:" ]; then |
40 | freepgs=$size | 38 | freepgs=$size |
@@ -53,7 +51,7 @@ if [ $freepgs -lt $hpages_test ]; then | |||
53 | fi | 51 | fi |
54 | printf "Not enough huge pages available (%d < %d)\n" \ | 52 | printf "Not enough huge pages available (%d < %d)\n" \ |
55 | $freepgs $needpgs | 53 | $freepgs $needpgs |
56 | exit 1 | 54 | exit $ksft_skip |
57 | fi | 55 | fi |
58 | 56 | ||
59 | # | 57 | # |
diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile index 686da510f989..e0a625e34f40 100644 --- a/tools/testing/selftests/memory-hotplug/Makefile +++ b/tools/testing/selftests/memory-hotplug/Makefile | |||
@@ -4,11 +4,8 @@ all: | |||
4 | include ../lib.mk | 4 | include ../lib.mk |
5 | 5 | ||
6 | TEST_PROGS := mem-on-off-test.sh | 6 | TEST_PROGS := mem-on-off-test.sh |
7 | override RUN_TESTS := @./mem-on-off-test.sh -r 2 && echo "selftests: memory-hotplug [PASS]" || echo "selftests: memory-hotplug [FAIL]" | ||
8 | |||
9 | override EMIT_TESTS := echo "$(subst @,,$(RUN_TESTS))" | ||
10 | 7 | ||
11 | run_full_test: | 8 | run_full_test: |
12 | @/bin/bash ./mem-on-off-test.sh && echo "memory-hotplug selftests: [PASS]" || echo "memory-hotplug selftests: [FAIL]" | 9 | @/bin/bash ./mem-on-off-test.sh -r 10 && echo "memory-hotplug selftests: [PASS]" || echo "memory-hotplug selftests: [FAIL]" |
13 | 10 | ||
14 | clean: | 11 | clean: |
diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index ae2c790d0880..b37585e6aa38 100755 --- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh | |||
@@ -3,30 +3,33 @@ | |||
3 | 3 | ||
4 | SYSFS= | 4 | SYSFS= |
5 | 5 | ||
6 | # Kselftest framework requirement - SKIP code is 4. | ||
7 | ksft_skip=4 | ||
8 | |||
6 | prerequisite() | 9 | prerequisite() |
7 | { | 10 | { |
8 | msg="skip all tests:" | 11 | msg="skip all tests:" |
9 | 12 | ||
10 | if [ $UID != 0 ]; then | 13 | if [ $UID != 0 ]; then |
11 | echo $msg must be run as root >&2 | 14 | echo $msg must be run as root >&2 |
12 | exit 0 | 15 | exit $ksft_skip |
13 | fi | 16 | fi |
14 | 17 | ||
15 | SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` | 18 | SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` |
16 | 19 | ||
17 | if [ ! -d "$SYSFS" ]; then | 20 | if [ ! -d "$SYSFS" ]; then |
18 | echo $msg sysfs is not mounted >&2 | 21 | echo $msg sysfs is not mounted >&2 |
19 | exit 0 | 22 | exit $ksft_skip |
20 | fi | 23 | fi |
21 | 24 | ||
22 | if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then | 25 | if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then |
23 | echo $msg memory hotplug is not supported >&2 | 26 | echo $msg memory hotplug is not supported >&2 |
24 | exit 0 | 27 | exit $ksft_skip |
25 | fi | 28 | fi |
26 | 29 | ||
27 | if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then | 30 | if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then |
28 | echo $msg no hot-pluggable memory >&2 | 31 | echo $msg no hot-pluggable memory >&2 |
29 | exit 0 | 32 | exit $ksft_skip |
30 | fi | 33 | fi |
31 | } | 34 | } |
32 | 35 | ||
@@ -133,7 +136,8 @@ offline_memory_expect_fail() | |||
133 | 136 | ||
134 | error=-12 | 137 | error=-12 |
135 | priority=0 | 138 | priority=0 |
136 | ratio=10 | 139 | # Run with default of ratio=2 for Kselftest run |
140 | ratio=2 | ||
137 | retval=0 | 141 | retval=0 |
138 | 142 | ||
139 | while getopts e:hp:r: opt; do | 143 | while getopts e:hp:r: opt; do |
diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile index e094f71c6dbc..026890744215 100644 --- a/tools/testing/selftests/mount/Makefile +++ b/tools/testing/selftests/mount/Makefile | |||
@@ -3,15 +3,7 @@ | |||
3 | CFLAGS = -Wall \ | 3 | CFLAGS = -Wall \ |
4 | -O2 | 4 | -O2 |
5 | 5 | ||
6 | TEST_GEN_PROGS := unprivileged-remount-test | 6 | TEST_PROGS := run_tests.sh |
7 | TEST_GEN_FILES := unprivileged-remount-test | ||
7 | 8 | ||
8 | include ../lib.mk | 9 | include ../lib.mk |
9 | |||
10 | override RUN_TESTS := if [ -f /proc/self/uid_map ] ; \ | ||
11 | then \ | ||
12 | ./unprivileged-remount-test ; \ | ||
13 | else \ | ||
14 | echo "WARN: No /proc/self/uid_map exist, test skipped." ; \ | ||
15 | fi | ||
16 | override EMIT_TESTS := echo "$(RUN_TESTS)" | ||
17 | |||
diff --git a/tools/testing/selftests/mount/run_tests.sh b/tools/testing/selftests/mount/run_tests.sh new file mode 100755 index 000000000000..4ab8f507dcba --- /dev/null +++ b/tools/testing/selftests/mount/run_tests.sh | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | # Kselftest framework requirement - SKIP code is 4. | ||
4 | ksft_skip=4 | ||
5 | |||
6 | # Run mount selftests | ||
7 | if [ -f /proc/self/uid_map ] ; then | ||
8 | ./unprivileged-remount-test ; | ||
9 | else | ||
10 | echo "WARN: No /proc/self/uid_map exist, test skipped." ; | ||
11 | exit $ksft_skip | ||
12 | fi | ||
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile index 743d3f9e5918..8a58055fc1f5 100644 --- a/tools/testing/selftests/mqueue/Makefile +++ b/tools/testing/selftests/mqueue/Makefile | |||
@@ -1,17 +1,7 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | CFLAGS += -O2 | 2 | CFLAGS += -O2 |
3 | LDLIBS = -lrt -lpthread -lpopt | 3 | LDLIBS = -lrt -lpthread -lpopt |
4 | |||
4 | TEST_GEN_PROGS := mq_open_tests mq_perf_tests | 5 | TEST_GEN_PROGS := mq_open_tests mq_perf_tests |
5 | 6 | ||
6 | include ../lib.mk | 7 | include ../lib.mk |
7 | |||
8 | override define RUN_TESTS | ||
9 | @$(OUTPUT)/mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]" | ||
10 | @$(OUTPUT)/mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" | ||
11 | endef | ||
12 | |||
13 | override define EMIT_TESTS | ||
14 | echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\"" | ||
15 | echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\"" | ||
16 | endef | ||
17 | |||
diff --git a/tools/testing/selftests/mqueue/mq_open_tests.c b/tools/testing/selftests/mqueue/mq_open_tests.c index e0a74bd207a5..9403ac01ba11 100644 --- a/tools/testing/selftests/mqueue/mq_open_tests.c +++ b/tools/testing/selftests/mqueue/mq_open_tests.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <mqueue.h> | 33 | #include <mqueue.h> |
34 | #include <error.h> | 34 | #include <error.h> |
35 | 35 | ||
36 | #include "../kselftest.h" | ||
37 | |||
36 | static char *usage = | 38 | static char *usage = |
37 | "Usage:\n" | 39 | "Usage:\n" |
38 | " %s path\n" | 40 | " %s path\n" |
@@ -53,6 +55,7 @@ int saved_def_msgs, saved_def_msgsize, saved_max_msgs, saved_max_msgsize; | |||
53 | int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize; | 55 | int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize; |
54 | FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize; | 56 | FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize; |
55 | char *queue_path; | 57 | char *queue_path; |
58 | char *default_queue_path = "/test1"; | ||
56 | mqd_t queue = -1; | 59 | mqd_t queue = -1; |
57 | 60 | ||
58 | static inline void __set(FILE *stream, int value, char *err_msg); | 61 | static inline void __set(FILE *stream, int value, char *err_msg); |
@@ -238,35 +241,33 @@ int main(int argc, char *argv[]) | |||
238 | struct mq_attr attr, result; | 241 | struct mq_attr attr, result; |
239 | 242 | ||
240 | if (argc != 2) { | 243 | if (argc != 2) { |
241 | fprintf(stderr, "Must pass a valid queue name\n\n"); | 244 | printf("Using Default queue path - %s\n", default_queue_path); |
242 | fprintf(stderr, usage, argv[0]); | 245 | queue_path = default_queue_path; |
243 | exit(1); | 246 | } else { |
244 | } | ||
245 | 247 | ||
246 | /* | 248 | /* |
247 | * Although we can create a msg queue with a non-absolute path name, | 249 | * Although we can create a msg queue with a non-absolute path name, |
248 | * unlink will fail. So, if the name doesn't start with a /, add one | 250 | * unlink will fail. So, if the name doesn't start with a /, add one |
249 | * when we save it. | 251 | * when we save it. |
250 | */ | 252 | */ |
251 | if (*argv[1] == '/') | 253 | if (*argv[1] == '/') |
252 | queue_path = strdup(argv[1]); | 254 | queue_path = strdup(argv[1]); |
253 | else { | 255 | else { |
254 | queue_path = malloc(strlen(argv[1]) + 2); | 256 | queue_path = malloc(strlen(argv[1]) + 2); |
255 | if (!queue_path) { | 257 | if (!queue_path) { |
256 | perror("malloc()"); | 258 | perror("malloc()"); |
257 | exit(1); | 259 | exit(1); |
260 | } | ||
261 | queue_path[0] = '/'; | ||
262 | queue_path[1] = 0; | ||
263 | strcat(queue_path, argv[1]); | ||
258 | } | 264 | } |
259 | queue_path[0] = '/'; | ||
260 | queue_path[1] = 0; | ||
261 | strcat(queue_path, argv[1]); | ||
262 | } | 265 | } |
263 | 266 | ||
264 | if (getuid() != 0) { | 267 | if (getuid() != 0) |
265 | fprintf(stderr, "Not running as root, but almost all tests " | 268 | ksft_exit_skip("Not running as root, but almost all tests " |
266 | "require root in order to modify\nsystem settings. " | 269 | "require root in order to modify\nsystem settings. " |
267 | "Exiting.\n"); | 270 | "Exiting.\n"); |
268 | exit(1); | ||
269 | } | ||
270 | 271 | ||
271 | /* Find out what files there are for us to make tweaks in */ | 272 | /* Find out what files there are for us to make tweaks in */ |
272 | def_msgs = fopen(DEF_MSGS, "r+"); | 273 | def_msgs = fopen(DEF_MSGS, "r+"); |
diff --git a/tools/testing/selftests/mqueue/mq_perf_tests.c b/tools/testing/selftests/mqueue/mq_perf_tests.c index 8188f72de93c..b019e0b8221c 100644 --- a/tools/testing/selftests/mqueue/mq_perf_tests.c +++ b/tools/testing/selftests/mqueue/mq_perf_tests.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <popt.h> | 39 | #include <popt.h> |
40 | #include <error.h> | 40 | #include <error.h> |
41 | 41 | ||
42 | #include "../kselftest.h" | ||
43 | |||
42 | static char *usage = | 44 | static char *usage = |
43 | "Usage:\n" | 45 | "Usage:\n" |
44 | " %s [-c #[,#..] -f] path\n" | 46 | " %s [-c #[,#..] -f] path\n" |
@@ -626,12 +628,10 @@ int main(int argc, char *argv[]) | |||
626 | cpus_to_pin[0] = cpus_online - 1; | 628 | cpus_to_pin[0] = cpus_online - 1; |
627 | } | 629 | } |
628 | 630 | ||
629 | if (getuid() != 0) { | 631 | if (getuid() != 0) |
630 | fprintf(stderr, "Not running as root, but almost all tests " | 632 | ksft_exit_skip("Not running as root, but almost all tests " |
631 | "require root in order to modify\nsystem settings. " | 633 | "require root in order to modify\nsystem settings. " |
632 | "Exiting.\n"); | 634 | "Exiting.\n"); |
633 | exit(1); | ||
634 | } | ||
635 | 635 | ||
636 | max_msgs = fopen(MAX_MSGS, "r+"); | 636 | max_msgs = fopen(MAX_MSGS, "r+"); |
637 | max_msgsize = fopen(MAX_MSGSIZE, "r+"); | 637 | max_msgsize = fopen(MAX_MSGSIZE, "r+"); |
diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index 9164e60d4b66..5baac82b9287 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh | |||
@@ -5,6 +5,8 @@ | |||
5 | # different events. | 5 | # different events. |
6 | 6 | ||
7 | ret=0 | 7 | ret=0 |
8 | # Kselftest framework requirement - SKIP code is 4. | ||
9 | ksft_skip=4 | ||
8 | 10 | ||
9 | VERBOSE=${VERBOSE:=0} | 11 | VERBOSE=${VERBOSE:=0} |
10 | PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} | 12 | PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} |
@@ -579,18 +581,18 @@ fib_test() | |||
579 | 581 | ||
580 | if [ "$(id -u)" -ne 0 ];then | 582 | if [ "$(id -u)" -ne 0 ];then |
581 | echo "SKIP: Need root privileges" | 583 | echo "SKIP: Need root privileges" |
582 | exit 0 | 584 | exit $ksft_skip; |
583 | fi | 585 | fi |
584 | 586 | ||
585 | if [ ! -x "$(command -v ip)" ]; then | 587 | if [ ! -x "$(command -v ip)" ]; then |
586 | echo "SKIP: Could not run test without ip tool" | 588 | echo "SKIP: Could not run test without ip tool" |
587 | exit 0 | 589 | exit $ksft_skip |
588 | fi | 590 | fi |
589 | 591 | ||
590 | ip route help 2>&1 | grep -q fibmatch | 592 | ip route help 2>&1 | grep -q fibmatch |
591 | if [ $? -ne 0 ]; then | 593 | if [ $? -ne 0 ]; then |
592 | echo "SKIP: iproute2 too old, missing fibmatch" | 594 | echo "SKIP: iproute2 too old, missing fibmatch" |
593 | exit 0 | 595 | exit $ksft_skip |
594 | fi | 596 | fi |
595 | 597 | ||
596 | # start clean | 598 | # start clean |
diff --git a/tools/testing/selftests/net/netdevice.sh b/tools/testing/selftests/net/netdevice.sh index 903679e0ff31..e3afcb424710 100755 --- a/tools/testing/selftests/net/netdevice.sh +++ b/tools/testing/selftests/net/netdevice.sh | |||
@@ -8,6 +8,9 @@ | |||
8 | # if not they probably have failed earlier in the boot process and their logged error will be catched by another test | 8 | # if not they probably have failed earlier in the boot process and their logged error will be catched by another test |
9 | # | 9 | # |
10 | 10 | ||
11 | # Kselftest framework requirement - SKIP code is 4. | ||
12 | ksft_skip=4 | ||
13 | |||
11 | # this function will try to up the interface | 14 | # this function will try to up the interface |
12 | # if already up, nothing done | 15 | # if already up, nothing done |
13 | # arg1: network interface name | 16 | # arg1: network interface name |
@@ -18,7 +21,7 @@ kci_net_start() | |||
18 | ip link show "$netdev" |grep -q UP | 21 | ip link show "$netdev" |grep -q UP |
19 | if [ $? -eq 0 ];then | 22 | if [ $? -eq 0 ];then |
20 | echo "SKIP: $netdev: interface already up" | 23 | echo "SKIP: $netdev: interface already up" |
21 | return 0 | 24 | return $ksft_skip |
22 | fi | 25 | fi |
23 | 26 | ||
24 | ip link set "$netdev" up | 27 | ip link set "$netdev" up |
@@ -61,12 +64,12 @@ kci_net_setup() | |||
61 | ip address show "$netdev" |grep '^[[:space:]]*inet' | 64 | ip address show "$netdev" |grep '^[[:space:]]*inet' |
62 | if [ $? -eq 0 ];then | 65 | if [ $? -eq 0 ];then |
63 | echo "SKIP: $netdev: already have an IP" | 66 | echo "SKIP: $netdev: already have an IP" |
64 | return 0 | 67 | return $ksft_skip |
65 | fi | 68 | fi |
66 | 69 | ||
67 | # TODO what ipaddr to set ? DHCP ? | 70 | # TODO what ipaddr to set ? DHCP ? |
68 | echo "SKIP: $netdev: set IP address" | 71 | echo "SKIP: $netdev: set IP address" |
69 | return 0 | 72 | return $ksft_skip |
70 | } | 73 | } |
71 | 74 | ||
72 | # test an ethtool command | 75 | # test an ethtool command |
@@ -84,6 +87,7 @@ kci_netdev_ethtool_test() | |||
84 | if [ $ret -ne 0 ];then | 87 | if [ $ret -ne 0 ];then |
85 | if [ $ret -eq "$1" ];then | 88 | if [ $ret -eq "$1" ];then |
86 | echo "SKIP: $netdev: ethtool $2 not supported" | 89 | echo "SKIP: $netdev: ethtool $2 not supported" |
90 | return $ksft_skip | ||
87 | else | 91 | else |
88 | echo "FAIL: $netdev: ethtool $2" | 92 | echo "FAIL: $netdev: ethtool $2" |
89 | return 1 | 93 | return 1 |
@@ -104,7 +108,7 @@ kci_netdev_ethtool() | |||
104 | ethtool --version 2>/dev/null >/dev/null | 108 | ethtool --version 2>/dev/null >/dev/null |
105 | if [ $? -ne 0 ];then | 109 | if [ $? -ne 0 ];then |
106 | echo "SKIP: ethtool not present" | 110 | echo "SKIP: ethtool not present" |
107 | return 1 | 111 | return $ksft_skip |
108 | fi | 112 | fi |
109 | 113 | ||
110 | TMP_ETHTOOL_FEATURES="$(mktemp)" | 114 | TMP_ETHTOOL_FEATURES="$(mktemp)" |
@@ -176,13 +180,13 @@ kci_test_netdev() | |||
176 | #check for needed privileges | 180 | #check for needed privileges |
177 | if [ "$(id -u)" -ne 0 ];then | 181 | if [ "$(id -u)" -ne 0 ];then |
178 | echo "SKIP: Need root privileges" | 182 | echo "SKIP: Need root privileges" |
179 | exit 0 | 183 | exit $ksft_skip |
180 | fi | 184 | fi |
181 | 185 | ||
182 | ip link show 2>/dev/null >/dev/null | 186 | ip link show 2>/dev/null >/dev/null |
183 | if [ $? -ne 0 ];then | 187 | if [ $? -ne 0 ];then |
184 | echo "SKIP: Could not run test without the ip tool" | 188 | echo "SKIP: Could not run test without the ip tool" |
185 | exit 0 | 189 | exit $ksft_skip |
186 | fi | 190 | fi |
187 | 191 | ||
188 | TMP_LIST_NETDEV="$(mktemp)" | 192 | TMP_LIST_NETDEV="$(mktemp)" |
diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh index 1e428781a625..7514f93e1624 100755 --- a/tools/testing/selftests/net/pmtu.sh +++ b/tools/testing/selftests/net/pmtu.sh | |||
@@ -43,6 +43,9 @@ | |||
43 | # that MTU is properly calculated instead when MTU is not configured from | 43 | # that MTU is properly calculated instead when MTU is not configured from |
44 | # userspace | 44 | # userspace |
45 | 45 | ||
46 | # Kselftest framework requirement - SKIP code is 4. | ||
47 | ksft_skip=4 | ||
48 | |||
46 | tests=" | 49 | tests=" |
47 | pmtu_vti6_exception vti6: PMTU exceptions | 50 | pmtu_vti6_exception vti6: PMTU exceptions |
48 | pmtu_vti4_exception vti4: PMTU exceptions | 51 | pmtu_vti4_exception vti4: PMTU exceptions |
@@ -162,7 +165,7 @@ setup_xfrm6() { | |||
162 | } | 165 | } |
163 | 166 | ||
164 | setup() { | 167 | setup() { |
165 | [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return 1 | 168 | [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip |
166 | 169 | ||
167 | cleanup_done=0 | 170 | cleanup_done=0 |
168 | for arg do | 171 | for arg do |
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c index 7f6cd9fdacf3..7ec4fa4d55dc 100644 --- a/tools/testing/selftests/net/psock_tpacket.c +++ b/tools/testing/selftests/net/psock_tpacket.c | |||
@@ -60,6 +60,8 @@ | |||
60 | 60 | ||
61 | #include "psock_lib.h" | 61 | #include "psock_lib.h" |
62 | 62 | ||
63 | #include "../kselftest.h" | ||
64 | |||
63 | #ifndef bug_on | 65 | #ifndef bug_on |
64 | # define bug_on(cond) assert(!(cond)) | 66 | # define bug_on(cond) assert(!(cond)) |
65 | #endif | 67 | #endif |
@@ -825,7 +827,7 @@ static int test_tpacket(int version, int type) | |||
825 | fprintf(stderr, "test: skip %s %s since user and kernel " | 827 | fprintf(stderr, "test: skip %s %s since user and kernel " |
826 | "space have different bit width\n", | 828 | "space have different bit width\n", |
827 | tpacket_str[version], type_str[type]); | 829 | tpacket_str[version], type_str[type]); |
828 | return 0; | 830 | return KSFT_SKIP; |
829 | } | 831 | } |
830 | 832 | ||
831 | sock = pfsocket(version); | 833 | sock = pfsocket(version); |
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index e6f485235435..fb3767844e42 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh | |||
@@ -7,6 +7,9 @@ | |||
7 | devdummy="test-dummy0" | 7 | devdummy="test-dummy0" |
8 | ret=0 | 8 | ret=0 |
9 | 9 | ||
10 | # Kselftest framework requirement - SKIP code is 4. | ||
11 | ksft_skip=4 | ||
12 | |||
10 | # set global exit status, but never reset nonzero one. | 13 | # set global exit status, but never reset nonzero one. |
11 | check_err() | 14 | check_err() |
12 | { | 15 | { |
@@ -333,7 +336,7 @@ kci_test_vrf() | |||
333 | ip link show type vrf 2>/dev/null | 336 | ip link show type vrf 2>/dev/null |
334 | if [ $? -ne 0 ]; then | 337 | if [ $? -ne 0 ]; then |
335 | echo "SKIP: vrf: iproute2 too old" | 338 | echo "SKIP: vrf: iproute2 too old" |
336 | return 0 | 339 | return $ksft_skip |
337 | fi | 340 | fi |
338 | 341 | ||
339 | ip link add "$vrfname" type vrf table 10 | 342 | ip link add "$vrfname" type vrf table 10 |
@@ -409,7 +412,7 @@ kci_test_encap_fou() | |||
409 | ip fou help 2>&1 |grep -q 'Usage: ip fou' | 412 | ip fou help 2>&1 |grep -q 'Usage: ip fou' |
410 | if [ $? -ne 0 ];then | 413 | if [ $? -ne 0 ];then |
411 | echo "SKIP: fou: iproute2 too old" | 414 | echo "SKIP: fou: iproute2 too old" |
412 | return 1 | 415 | return $ksft_skip |
413 | fi | 416 | fi |
414 | 417 | ||
415 | ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null | 418 | ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null |
@@ -444,7 +447,7 @@ kci_test_encap() | |||
444 | ip netns add "$testns" | 447 | ip netns add "$testns" |
445 | if [ $? -ne 0 ]; then | 448 | if [ $? -ne 0 ]; then |
446 | echo "SKIP encap tests: cannot add net namespace $testns" | 449 | echo "SKIP encap tests: cannot add net namespace $testns" |
447 | return 1 | 450 | return $ksft_skip |
448 | fi | 451 | fi |
449 | 452 | ||
450 | ip netns exec "$testns" ip link set lo up | 453 | ip netns exec "$testns" ip link set lo up |
@@ -469,7 +472,7 @@ kci_test_macsec() | |||
469 | ip macsec help 2>&1 | grep -q "^Usage: ip macsec" | 472 | ip macsec help 2>&1 | grep -q "^Usage: ip macsec" |
470 | if [ $? -ne 0 ]; then | 473 | if [ $? -ne 0 ]; then |
471 | echo "SKIP: macsec: iproute2 too old" | 474 | echo "SKIP: macsec: iproute2 too old" |
472 | return 0 | 475 | return $ksft_skip |
473 | fi | 476 | fi |
474 | 477 | ||
475 | ip link add link "$devdummy" "$msname" type macsec port 42 encrypt on | 478 | ip link add link "$devdummy" "$msname" type macsec port 42 encrypt on |
@@ -511,14 +514,14 @@ kci_test_gretap() | |||
511 | ip netns add "$testns" | 514 | ip netns add "$testns" |
512 | if [ $? -ne 0 ]; then | 515 | if [ $? -ne 0 ]; then |
513 | echo "SKIP gretap tests: cannot add net namespace $testns" | 516 | echo "SKIP gretap tests: cannot add net namespace $testns" |
514 | return 1 | 517 | return $ksft_skip |
515 | fi | 518 | fi |
516 | 519 | ||
517 | ip link help gretap 2>&1 | grep -q "^Usage:" | 520 | ip link help gretap 2>&1 | grep -q "^Usage:" |
518 | if [ $? -ne 0 ];then | 521 | if [ $? -ne 0 ];then |
519 | echo "SKIP: gretap: iproute2 too old" | 522 | echo "SKIP: gretap: iproute2 too old" |
520 | ip netns del "$testns" | 523 | ip netns del "$testns" |
521 | return 1 | 524 | return $ksft_skip |
522 | fi | 525 | fi |
523 | 526 | ||
524 | # test native tunnel | 527 | # test native tunnel |
@@ -561,14 +564,14 @@ kci_test_ip6gretap() | |||
561 | ip netns add "$testns" | 564 | ip netns add "$testns" |
562 | if [ $? -ne 0 ]; then | 565 | if [ $? -ne 0 ]; then |
563 | echo "SKIP ip6gretap tests: cannot add net namespace $testns" | 566 | echo "SKIP ip6gretap tests: cannot add net namespace $testns" |
564 | return 1 | 567 | return $ksft_skip |
565 | fi | 568 | fi |
566 | 569 | ||
567 | ip link help ip6gretap 2>&1 | grep -q "^Usage:" | 570 | ip link help ip6gretap 2>&1 | grep -q "^Usage:" |
568 | if [ $? -ne 0 ];then | 571 | if [ $? -ne 0 ];then |
569 | echo "SKIP: ip6gretap: iproute2 too old" | 572 | echo "SKIP: ip6gretap: iproute2 too old" |
570 | ip netns del "$testns" | 573 | ip netns del "$testns" |
571 | return 1 | 574 | return $ksft_skip |
572 | fi | 575 | fi |
573 | 576 | ||
574 | # test native tunnel | 577 | # test native tunnel |
@@ -611,13 +614,13 @@ kci_test_erspan() | |||
611 | ip link help erspan 2>&1 | grep -q "^Usage:" | 614 | ip link help erspan 2>&1 | grep -q "^Usage:" |
612 | if [ $? -ne 0 ];then | 615 | if [ $? -ne 0 ];then |
613 | echo "SKIP: erspan: iproute2 too old" | 616 | echo "SKIP: erspan: iproute2 too old" |
614 | return 1 | 617 | return $ksft_skip |
615 | fi | 618 | fi |
616 | 619 | ||
617 | ip netns add "$testns" | 620 | ip netns add "$testns" |
618 | if [ $? -ne 0 ]; then | 621 | if [ $? -ne 0 ]; then |
619 | echo "SKIP erspan tests: cannot add net namespace $testns" | 622 | echo "SKIP erspan tests: cannot add net namespace $testns" |
620 | return 1 | 623 | return $ksft_skip |
621 | fi | 624 | fi |
622 | 625 | ||
623 | # test native tunnel erspan v1 | 626 | # test native tunnel erspan v1 |
@@ -676,13 +679,13 @@ kci_test_ip6erspan() | |||
676 | ip link help ip6erspan 2>&1 | grep -q "^Usage:" | 679 | ip link help ip6erspan 2>&1 | grep -q "^Usage:" |
677 | if [ $? -ne 0 ];then | 680 | if [ $? -ne 0 ];then |
678 | echo "SKIP: ip6erspan: iproute2 too old" | 681 | echo "SKIP: ip6erspan: iproute2 too old" |
679 | return 1 | 682 | return $ksft_skip |
680 | fi | 683 | fi |
681 | 684 | ||
682 | ip netns add "$testns" | 685 | ip netns add "$testns" |
683 | if [ $? -ne 0 ]; then | 686 | if [ $? -ne 0 ]; then |
684 | echo "SKIP ip6erspan tests: cannot add net namespace $testns" | 687 | echo "SKIP ip6erspan tests: cannot add net namespace $testns" |
685 | return 1 | 688 | return $ksft_skip |
686 | fi | 689 | fi |
687 | 690 | ||
688 | # test native tunnel ip6erspan v1 | 691 | # test native tunnel ip6erspan v1 |
@@ -762,14 +765,14 @@ kci_test_rtnl() | |||
762 | #check for needed privileges | 765 | #check for needed privileges |
763 | if [ "$(id -u)" -ne 0 ];then | 766 | if [ "$(id -u)" -ne 0 ];then |
764 | echo "SKIP: Need root privileges" | 767 | echo "SKIP: Need root privileges" |
765 | exit 0 | 768 | exit $ksft_skip |
766 | fi | 769 | fi |
767 | 770 | ||
768 | for x in ip tc;do | 771 | for x in ip tc;do |
769 | $x -Version 2>/dev/null >/dev/null | 772 | $x -Version 2>/dev/null >/dev/null |
770 | if [ $? -ne 0 ];then | 773 | if [ $? -ne 0 ];then |
771 | echo "SKIP: Could not run test without the $x tool" | 774 | echo "SKIP: Could not run test without the $x tool" |
772 | exit 0 | 775 | exit $ksft_skip |
773 | fi | 776 | fi |
774 | done | 777 | done |
775 | 778 | ||
diff --git a/tools/testing/selftests/rtc/.gitignore b/tools/testing/selftests/rtc/.gitignore new file mode 100644 index 000000000000..d0ad44f6294a --- /dev/null +++ b/tools/testing/selftests/rtc/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | rtctest | ||
2 | setdate | ||
diff --git a/tools/testing/selftests/rtc/Makefile b/tools/testing/selftests/rtc/Makefile new file mode 100644 index 000000000000..de9c8566672a --- /dev/null +++ b/tools/testing/selftests/rtc/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | CFLAGS += -O3 -Wl,-no-as-needed -Wall | ||
3 | LDFLAGS += -lrt -lpthread -lm | ||
4 | |||
5 | TEST_GEN_PROGS = rtctest | ||
6 | |||
7 | TEST_GEN_PROGS_EXTENDED = setdate | ||
8 | |||
9 | include ../lib.mk | ||
diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c new file mode 100644 index 000000000000..e20b017e7073 --- /dev/null +++ b/tools/testing/selftests/rtc/rtctest.c | |||
@@ -0,0 +1,238 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Real Time Clock Driver Test Program | ||
4 | * | ||
5 | * Copyright (c) 2018 Alexandre Belloni <alexandre.belloni@bootlin.com> | ||
6 | */ | ||
7 | |||
8 | #include <errno.h> | ||
9 | #include <fcntl.h> | ||
10 | #include <linux/rtc.h> | ||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <sys/ioctl.h> | ||
14 | #include <sys/time.h> | ||
15 | #include <sys/types.h> | ||
16 | #include <time.h> | ||
17 | #include <unistd.h> | ||
18 | |||
19 | #include "../kselftest_harness.h" | ||
20 | |||
21 | #define NUM_UIE 3 | ||
22 | #define ALARM_DELTA 3 | ||
23 | |||
24 | static char *rtc_file = "/dev/rtc0"; | ||
25 | |||
26 | FIXTURE(rtc) { | ||
27 | int fd; | ||
28 | }; | ||
29 | |||
30 | FIXTURE_SETUP(rtc) { | ||
31 | self->fd = open(rtc_file, O_RDONLY); | ||
32 | ASSERT_NE(-1, self->fd); | ||
33 | } | ||
34 | |||
35 | FIXTURE_TEARDOWN(rtc) { | ||
36 | close(self->fd); | ||
37 | } | ||
38 | |||
39 | TEST_F(rtc, date_read) { | ||
40 | int rc; | ||
41 | struct rtc_time rtc_tm; | ||
42 | |||
43 | /* Read the RTC time/date */ | ||
44 | rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm); | ||
45 | ASSERT_NE(-1, rc); | ||
46 | |||
47 | TH_LOG("Current RTC date/time is %02d/%02d/%02d %02d:%02d:%02d.", | ||
48 | rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, | ||
49 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); | ||
50 | } | ||
51 | |||
52 | TEST_F(rtc, uie_read) { | ||
53 | int i, rc, irq = 0; | ||
54 | unsigned long data; | ||
55 | |||
56 | /* Turn on update interrupts */ | ||
57 | rc = ioctl(self->fd, RTC_UIE_ON, 0); | ||
58 | if (rc == -1) { | ||
59 | ASSERT_EQ(EINVAL, errno); | ||
60 | TH_LOG("skip update IRQs not supported."); | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | for (i = 0; i < NUM_UIE; i++) { | ||
65 | /* This read will block */ | ||
66 | rc = read(self->fd, &data, sizeof(data)); | ||
67 | ASSERT_NE(-1, rc); | ||
68 | irq++; | ||
69 | } | ||
70 | |||
71 | EXPECT_EQ(NUM_UIE, irq); | ||
72 | |||
73 | rc = ioctl(self->fd, RTC_UIE_OFF, 0); | ||
74 | ASSERT_NE(-1, rc); | ||
75 | } | ||
76 | |||
77 | TEST_F(rtc, uie_select) { | ||
78 | int i, rc, irq = 0; | ||
79 | unsigned long data; | ||
80 | |||
81 | /* Turn on update interrupts */ | ||
82 | rc = ioctl(self->fd, RTC_UIE_ON, 0); | ||
83 | if (rc == -1) { | ||
84 | ASSERT_EQ(EINVAL, errno); | ||
85 | TH_LOG("skip update IRQs not supported."); | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | for (i = 0; i < NUM_UIE; i++) { | ||
90 | struct timeval tv = { .tv_sec = 2 }; | ||
91 | fd_set readfds; | ||
92 | |||
93 | FD_ZERO(&readfds); | ||
94 | FD_SET(self->fd, &readfds); | ||
95 | /* The select will wait until an RTC interrupt happens. */ | ||
96 | rc = select(self->fd + 1, &readfds, NULL, NULL, &tv); | ||
97 | ASSERT_NE(-1, rc); | ||
98 | ASSERT_NE(0, rc); | ||
99 | |||
100 | /* This read won't block */ | ||
101 | rc = read(self->fd, &data, sizeof(unsigned long)); | ||
102 | ASSERT_NE(-1, rc); | ||
103 | irq++; | ||
104 | } | ||
105 | |||
106 | EXPECT_EQ(NUM_UIE, irq); | ||
107 | |||
108 | rc = ioctl(self->fd, RTC_UIE_OFF, 0); | ||
109 | ASSERT_NE(-1, rc); | ||
110 | } | ||
111 | |||
112 | TEST_F(rtc, alarm_alm_set) { | ||
113 | struct timeval tv = { .tv_sec = ALARM_DELTA + 2 }; | ||
114 | unsigned long data; | ||
115 | struct rtc_time tm; | ||
116 | fd_set readfds; | ||
117 | time_t secs, new; | ||
118 | int rc; | ||
119 | |||
120 | rc = ioctl(self->fd, RTC_RD_TIME, &tm); | ||
121 | ASSERT_NE(-1, rc); | ||
122 | |||
123 | secs = timegm((struct tm *)&tm) + ALARM_DELTA; | ||
124 | gmtime_r(&secs, (struct tm *)&tm); | ||
125 | |||
126 | rc = ioctl(self->fd, RTC_ALM_SET, &tm); | ||
127 | if (rc == -1) { | ||
128 | ASSERT_EQ(EINVAL, errno); | ||
129 | TH_LOG("skip alarms are not supported."); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | rc = ioctl(self->fd, RTC_ALM_READ, &tm); | ||
134 | ASSERT_NE(-1, rc); | ||
135 | |||
136 | TH_LOG("Alarm time now set to %02d:%02d:%02d.", | ||
137 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
138 | |||
139 | /* Enable alarm interrupts */ | ||
140 | rc = ioctl(self->fd, RTC_AIE_ON, 0); | ||
141 | ASSERT_NE(-1, rc); | ||
142 | |||
143 | FD_ZERO(&readfds); | ||
144 | FD_SET(self->fd, &readfds); | ||
145 | |||
146 | rc = select(self->fd + 1, &readfds, NULL, NULL, &tv); | ||
147 | ASSERT_NE(-1, rc); | ||
148 | EXPECT_NE(0, rc); | ||
149 | |||
150 | /* Disable alarm interrupts */ | ||
151 | rc = ioctl(self->fd, RTC_AIE_OFF, 0); | ||
152 | ASSERT_NE(-1, rc); | ||
153 | |||
154 | if (rc == 0) | ||
155 | return; | ||
156 | |||
157 | rc = read(self->fd, &data, sizeof(unsigned long)); | ||
158 | ASSERT_NE(-1, rc); | ||
159 | TH_LOG("data: %lx", data); | ||
160 | |||
161 | rc = ioctl(self->fd, RTC_RD_TIME, &tm); | ||
162 | ASSERT_NE(-1, rc); | ||
163 | |||
164 | new = timegm((struct tm *)&tm); | ||
165 | ASSERT_EQ(new, secs); | ||
166 | } | ||
167 | |||
168 | TEST_F(rtc, alarm_wkalm_set) { | ||
169 | struct timeval tv = { .tv_sec = ALARM_DELTA + 2 }; | ||
170 | struct rtc_wkalrm alarm = { 0 }; | ||
171 | struct rtc_time tm; | ||
172 | unsigned long data; | ||
173 | fd_set readfds; | ||
174 | time_t secs, new; | ||
175 | int rc; | ||
176 | |||
177 | rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time); | ||
178 | ASSERT_NE(-1, rc); | ||
179 | |||
180 | secs = timegm((struct tm *)&alarm.time) + ALARM_DELTA; | ||
181 | gmtime_r(&secs, (struct tm *)&alarm.time); | ||
182 | |||
183 | alarm.enabled = 1; | ||
184 | |||
185 | rc = ioctl(self->fd, RTC_WKALM_SET, &alarm); | ||
186 | if (rc == -1) { | ||
187 | ASSERT_EQ(EINVAL, errno); | ||
188 | TH_LOG("skip alarms are not supported."); | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | rc = ioctl(self->fd, RTC_WKALM_RD, &alarm); | ||
193 | ASSERT_NE(-1, rc); | ||
194 | |||
195 | TH_LOG("Alarm time now set to %02d/%02d/%02d %02d:%02d:%02d.", | ||
196 | alarm.time.tm_mday, alarm.time.tm_mon + 1, | ||
197 | alarm.time.tm_year + 1900, alarm.time.tm_hour, | ||
198 | alarm.time.tm_min, alarm.time.tm_sec); | ||
199 | |||
200 | FD_ZERO(&readfds); | ||
201 | FD_SET(self->fd, &readfds); | ||
202 | |||
203 | rc = select(self->fd + 1, &readfds, NULL, NULL, &tv); | ||
204 | ASSERT_NE(-1, rc); | ||
205 | EXPECT_NE(0, rc); | ||
206 | |||
207 | rc = read(self->fd, &data, sizeof(unsigned long)); | ||
208 | ASSERT_NE(-1, rc); | ||
209 | |||
210 | rc = ioctl(self->fd, RTC_RD_TIME, &tm); | ||
211 | ASSERT_NE(-1, rc); | ||
212 | |||
213 | new = timegm((struct tm *)&tm); | ||
214 | ASSERT_EQ(new, secs); | ||
215 | } | ||
216 | |||
217 | static void __attribute__((constructor)) | ||
218 | __constructor_order_last(void) | ||
219 | { | ||
220 | if (!__constructor_order) | ||
221 | __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; | ||
222 | } | ||
223 | |||
224 | int main(int argc, char **argv) | ||
225 | { | ||
226 | switch (argc) { | ||
227 | case 2: | ||
228 | rtc_file = argv[1]; | ||
229 | /* FALLTHROUGH */ | ||
230 | case 1: | ||
231 | break; | ||
232 | default: | ||
233 | fprintf(stderr, "usage: %s [rtcdev]\n", argv[0]); | ||
234 | return 1; | ||
235 | } | ||
236 | |||
237 | return test_harness_run(argc, argv); | ||
238 | } | ||
diff --git a/tools/testing/selftests/timers/rtctest_setdate.c b/tools/testing/selftests/rtc/setdate.c index 2cb78489eca4..2cb78489eca4 100644 --- a/tools/testing/selftests/timers/rtctest_setdate.c +++ b/tools/testing/selftests/rtc/setdate.c | |||
diff --git a/tools/testing/selftests/timers/.gitignore b/tools/testing/selftests/timers/.gitignore index 2c8ac8416299..32a9eadb2d4e 100644 --- a/tools/testing/selftests/timers/.gitignore +++ b/tools/testing/selftests/timers/.gitignore | |||
@@ -9,7 +9,7 @@ nanosleep | |||
9 | nsleep-lat | 9 | nsleep-lat |
10 | posix_timers | 10 | posix_timers |
11 | raw_skew | 11 | raw_skew |
12 | rtctest | 12 | rtcpie |
13 | set-2038 | 13 | set-2038 |
14 | set-tai | 14 | set-tai |
15 | set-timer-lat | 15 | set-timer-lat |
@@ -19,4 +19,3 @@ valid-adjtimex | |||
19 | adjtick | 19 | adjtick |
20 | set-tz | 20 | set-tz |
21 | freq-step | 21 | freq-step |
22 | rtctest_setdate | ||
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 3496680981f2..c02683cfb6c9 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile | |||
@@ -5,13 +5,13 @@ LDFLAGS += -lrt -lpthread -lm | |||
5 | # these are all "safe" tests that don't modify | 5 | # these are all "safe" tests that don't modify |
6 | # system time or require escalated privileges | 6 | # system time or require escalated privileges |
7 | TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ | 7 | TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ |
8 | inconsistency-check raw_skew threadtest rtctest | 8 | inconsistency-check raw_skew threadtest rtcpie |
9 | 9 | ||
10 | DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \ | 10 | DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \ |
11 | skew_consistency clocksource-switch freq-step leap-a-day \ | 11 | skew_consistency clocksource-switch freq-step leap-a-day \ |
12 | leapcrash set-tai set-2038 set-tz | 12 | leapcrash set-tai set-2038 set-tz |
13 | 13 | ||
14 | TEST_GEN_PROGS_EXTENDED = $(DESTRUCTIVE_TESTS) rtctest_setdate | 14 | TEST_GEN_PROGS_EXTENDED = $(DESTRUCTIVE_TESTS) |
15 | 15 | ||
16 | 16 | ||
17 | include ../lib.mk | 17 | include ../lib.mk |
diff --git a/tools/testing/selftests/timers/rtcpie.c b/tools/testing/selftests/timers/rtcpie.c new file mode 100644 index 000000000000..47b5bad1b393 --- /dev/null +++ b/tools/testing/selftests/timers/rtcpie.c | |||
@@ -0,0 +1,134 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Real Time Clock Periodic Interrupt test program | ||
4 | * | ||
5 | * Since commit 6610e0893b8bc ("RTC: Rework RTC code to use timerqueue for | ||
6 | * events"), PIE are completely handled using hrtimers, without actually using | ||
7 | * any underlying hardware RTC. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <linux/rtc.h> | ||
13 | #include <sys/ioctl.h> | ||
14 | #include <sys/time.h> | ||
15 | #include <sys/types.h> | ||
16 | #include <fcntl.h> | ||
17 | #include <unistd.h> | ||
18 | #include <stdlib.h> | ||
19 | #include <errno.h> | ||
20 | |||
21 | /* | ||
22 | * This expects the new RTC class driver framework, working with | ||
23 | * clocks that will often not be clones of what the PC-AT had. | ||
24 | * Use the command line to specify another RTC if you need one. | ||
25 | */ | ||
26 | static const char default_rtc[] = "/dev/rtc0"; | ||
27 | |||
28 | int main(int argc, char **argv) | ||
29 | { | ||
30 | int i, fd, retval, irqcount = 0; | ||
31 | unsigned long tmp, data, old_pie_rate; | ||
32 | const char *rtc = default_rtc; | ||
33 | struct timeval start, end, diff; | ||
34 | |||
35 | switch (argc) { | ||
36 | case 2: | ||
37 | rtc = argv[1]; | ||
38 | /* FALLTHROUGH */ | ||
39 | case 1: | ||
40 | break; | ||
41 | default: | ||
42 | fprintf(stderr, "usage: rtctest [rtcdev] [d]\n"); | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | fd = open(rtc, O_RDONLY); | ||
47 | |||
48 | if (fd == -1) { | ||
49 | perror(rtc); | ||
50 | exit(errno); | ||
51 | } | ||
52 | |||
53 | /* Read periodic IRQ rate */ | ||
54 | retval = ioctl(fd, RTC_IRQP_READ, &old_pie_rate); | ||
55 | if (retval == -1) { | ||
56 | /* not all RTCs support periodic IRQs */ | ||
57 | if (errno == EINVAL) { | ||
58 | fprintf(stderr, "\nNo periodic IRQ support\n"); | ||
59 | goto done; | ||
60 | } | ||
61 | perror("RTC_IRQP_READ ioctl"); | ||
62 | exit(errno); | ||
63 | } | ||
64 | fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", old_pie_rate); | ||
65 | |||
66 | fprintf(stderr, "Counting 20 interrupts at:"); | ||
67 | fflush(stderr); | ||
68 | |||
69 | /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ | ||
70 | for (tmp=2; tmp<=64; tmp*=2) { | ||
71 | |||
72 | retval = ioctl(fd, RTC_IRQP_SET, tmp); | ||
73 | if (retval == -1) { | ||
74 | /* not all RTCs can change their periodic IRQ rate */ | ||
75 | if (errno == EINVAL) { | ||
76 | fprintf(stderr, | ||
77 | "\n...Periodic IRQ rate is fixed\n"); | ||
78 | goto done; | ||
79 | } | ||
80 | perror("RTC_IRQP_SET ioctl"); | ||
81 | exit(errno); | ||
82 | } | ||
83 | |||
84 | fprintf(stderr, "\n%ldHz:\t", tmp); | ||
85 | fflush(stderr); | ||
86 | |||
87 | /* Enable periodic interrupts */ | ||
88 | retval = ioctl(fd, RTC_PIE_ON, 0); | ||
89 | if (retval == -1) { | ||
90 | perror("RTC_PIE_ON ioctl"); | ||
91 | exit(errno); | ||
92 | } | ||
93 | |||
94 | for (i=1; i<21; i++) { | ||
95 | gettimeofday(&start, NULL); | ||
96 | /* This blocks */ | ||
97 | retval = read(fd, &data, sizeof(unsigned long)); | ||
98 | if (retval == -1) { | ||
99 | perror("read"); | ||
100 | exit(errno); | ||
101 | } | ||
102 | gettimeofday(&end, NULL); | ||
103 | timersub(&end, &start, &diff); | ||
104 | if (diff.tv_sec > 0 || | ||
105 | diff.tv_usec > ((1000000L / tmp) * 1.10)) { | ||
106 | fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n", | ||
107 | diff.tv_sec, diff.tv_usec, | ||
108 | (1000000L / tmp)); | ||
109 | fflush(stdout); | ||
110 | exit(-1); | ||
111 | } | ||
112 | |||
113 | fprintf(stderr, " %d",i); | ||
114 | fflush(stderr); | ||
115 | irqcount++; | ||
116 | } | ||
117 | |||
118 | /* Disable periodic interrupts */ | ||
119 | retval = ioctl(fd, RTC_PIE_OFF, 0); | ||
120 | if (retval == -1) { | ||
121 | perror("RTC_PIE_OFF ioctl"); | ||
122 | exit(errno); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | done: | ||
127 | ioctl(fd, RTC_IRQP_SET, old_pie_rate); | ||
128 | |||
129 | fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); | ||
130 | |||
131 | close(fd); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c deleted file mode 100644 index 411eff625e66..000000000000 --- a/tools/testing/selftests/timers/rtctest.c +++ /dev/null | |||
@@ -1,403 +0,0 @@ | |||
1 | /* | ||
2 | * Real Time Clock Driver Test/Example Program | ||
3 | * | ||
4 | * Compile with: | ||
5 | * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest | ||
6 | * | ||
7 | * Copyright (C) 1996, Paul Gortmaker. | ||
8 | * | ||
9 | * Released under the GNU General Public License, version 2, | ||
10 | * included herein by reference. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <stdio.h> | ||
15 | #include <linux/rtc.h> | ||
16 | #include <sys/ioctl.h> | ||
17 | #include <sys/time.h> | ||
18 | #include <sys/types.h> | ||
19 | #include <fcntl.h> | ||
20 | #include <unistd.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <errno.h> | ||
23 | |||
24 | #ifndef ARRAY_SIZE | ||
25 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
26 | #endif | ||
27 | |||
28 | /* | ||
29 | * This expects the new RTC class driver framework, working with | ||
30 | * clocks that will often not be clones of what the PC-AT had. | ||
31 | * Use the command line to specify another RTC if you need one. | ||
32 | */ | ||
33 | static const char default_rtc[] = "/dev/rtc0"; | ||
34 | |||
35 | static struct rtc_time cutoff_dates[] = { | ||
36 | { | ||
37 | .tm_year = 70, /* 1970 -1900 */ | ||
38 | .tm_mday = 1, | ||
39 | }, | ||
40 | /* signed time_t 19/01/2038 3:14:08 */ | ||
41 | { | ||
42 | .tm_year = 138, | ||
43 | .tm_mday = 19, | ||
44 | }, | ||
45 | { | ||
46 | .tm_year = 138, | ||
47 | .tm_mday = 20, | ||
48 | }, | ||
49 | { | ||
50 | .tm_year = 199, /* 2099 -1900 */ | ||
51 | .tm_mday = 1, | ||
52 | }, | ||
53 | { | ||
54 | .tm_year = 200, /* 2100 -1900 */ | ||
55 | .tm_mday = 1, | ||
56 | }, | ||
57 | /* unsigned time_t 07/02/2106 7:28:15*/ | ||
58 | { | ||
59 | .tm_year = 205, | ||
60 | .tm_mon = 1, | ||
61 | .tm_mday = 7, | ||
62 | }, | ||
63 | { | ||
64 | .tm_year = 206, | ||
65 | .tm_mon = 1, | ||
66 | .tm_mday = 8, | ||
67 | }, | ||
68 | /* signed time on 64bit in nanoseconds 12/04/2262 01:47:16*/ | ||
69 | { | ||
70 | .tm_year = 362, | ||
71 | .tm_mon = 3, | ||
72 | .tm_mday = 12, | ||
73 | }, | ||
74 | { | ||
75 | .tm_year = 362, /* 2262 -1900 */ | ||
76 | .tm_mon = 3, | ||
77 | .tm_mday = 13, | ||
78 | }, | ||
79 | }; | ||
80 | |||
81 | static int compare_dates(struct rtc_time *a, struct rtc_time *b) | ||
82 | { | ||
83 | if (a->tm_year != b->tm_year || | ||
84 | a->tm_mon != b->tm_mon || | ||
85 | a->tm_mday != b->tm_mday || | ||
86 | a->tm_hour != b->tm_hour || | ||
87 | a->tm_min != b->tm_min || | ||
88 | ((b->tm_sec - a->tm_sec) > 1)) | ||
89 | return 1; | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | int main(int argc, char **argv) | ||
95 | { | ||
96 | int i, fd, retval, irqcount = 0, dangerous = 0; | ||
97 | unsigned long tmp, data; | ||
98 | struct rtc_time rtc_tm; | ||
99 | const char *rtc = default_rtc; | ||
100 | struct timeval start, end, diff; | ||
101 | |||
102 | switch (argc) { | ||
103 | case 3: | ||
104 | if (*argv[2] == 'd') | ||
105 | dangerous = 1; | ||
106 | case 2: | ||
107 | rtc = argv[1]; | ||
108 | /* FALLTHROUGH */ | ||
109 | case 1: | ||
110 | break; | ||
111 | default: | ||
112 | fprintf(stderr, "usage: rtctest [rtcdev] [d]\n"); | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | fd = open(rtc, O_RDONLY); | ||
117 | |||
118 | if (fd == -1) { | ||
119 | perror(rtc); | ||
120 | exit(errno); | ||
121 | } | ||
122 | |||
123 | fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); | ||
124 | |||
125 | /* Turn on update interrupts (one per second) */ | ||
126 | retval = ioctl(fd, RTC_UIE_ON, 0); | ||
127 | if (retval == -1) { | ||
128 | if (errno == EINVAL) { | ||
129 | fprintf(stderr, | ||
130 | "\n...Update IRQs not supported.\n"); | ||
131 | goto test_READ; | ||
132 | } | ||
133 | perror("RTC_UIE_ON ioctl"); | ||
134 | exit(errno); | ||
135 | } | ||
136 | |||
137 | fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", | ||
138 | rtc); | ||
139 | fflush(stderr); | ||
140 | for (i=1; i<6; i++) { | ||
141 | /* This read will block */ | ||
142 | retval = read(fd, &data, sizeof(unsigned long)); | ||
143 | if (retval == -1) { | ||
144 | perror("read"); | ||
145 | exit(errno); | ||
146 | } | ||
147 | fprintf(stderr, " %d",i); | ||
148 | fflush(stderr); | ||
149 | irqcount++; | ||
150 | } | ||
151 | |||
152 | fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); | ||
153 | fflush(stderr); | ||
154 | for (i=1; i<6; i++) { | ||
155 | struct timeval tv = {5, 0}; /* 5 second timeout on select */ | ||
156 | fd_set readfds; | ||
157 | |||
158 | FD_ZERO(&readfds); | ||
159 | FD_SET(fd, &readfds); | ||
160 | /* The select will wait until an RTC interrupt happens. */ | ||
161 | retval = select(fd+1, &readfds, NULL, NULL, &tv); | ||
162 | if (retval == -1) { | ||
163 | perror("select"); | ||
164 | exit(errno); | ||
165 | } | ||
166 | /* This read won't block unlike the select-less case above. */ | ||
167 | retval = read(fd, &data, sizeof(unsigned long)); | ||
168 | if (retval == -1) { | ||
169 | perror("read"); | ||
170 | exit(errno); | ||
171 | } | ||
172 | fprintf(stderr, " %d",i); | ||
173 | fflush(stderr); | ||
174 | irqcount++; | ||
175 | } | ||
176 | |||
177 | /* Turn off update interrupts */ | ||
178 | retval = ioctl(fd, RTC_UIE_OFF, 0); | ||
179 | if (retval == -1) { | ||
180 | perror("RTC_UIE_OFF ioctl"); | ||
181 | exit(errno); | ||
182 | } | ||
183 | |||
184 | test_READ: | ||
185 | /* Read the RTC time/date */ | ||
186 | retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); | ||
187 | if (retval == -1) { | ||
188 | perror("RTC_RD_TIME ioctl"); | ||
189 | exit(errno); | ||
190 | } | ||
191 | |||
192 | fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", | ||
193 | rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, | ||
194 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); | ||
195 | |||
196 | /* Set the alarm to 5 sec in the future, and check for rollover */ | ||
197 | rtc_tm.tm_sec += 5; | ||
198 | if (rtc_tm.tm_sec >= 60) { | ||
199 | rtc_tm.tm_sec %= 60; | ||
200 | rtc_tm.tm_min++; | ||
201 | } | ||
202 | if (rtc_tm.tm_min == 60) { | ||
203 | rtc_tm.tm_min = 0; | ||
204 | rtc_tm.tm_hour++; | ||
205 | } | ||
206 | if (rtc_tm.tm_hour == 24) | ||
207 | rtc_tm.tm_hour = 0; | ||
208 | |||
209 | retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); | ||
210 | if (retval == -1) { | ||
211 | if (errno == EINVAL) { | ||
212 | fprintf(stderr, | ||
213 | "\n...Alarm IRQs not supported.\n"); | ||
214 | goto test_PIE; | ||
215 | } | ||
216 | |||
217 | perror("RTC_ALM_SET ioctl"); | ||
218 | exit(errno); | ||
219 | } | ||
220 | |||
221 | /* Read the current alarm settings */ | ||
222 | retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); | ||
223 | if (retval == -1) { | ||
224 | if (errno == EINVAL) { | ||
225 | fprintf(stderr, | ||
226 | "\n...EINVAL reading current alarm setting.\n"); | ||
227 | goto test_PIE; | ||
228 | } | ||
229 | perror("RTC_ALM_READ ioctl"); | ||
230 | exit(errno); | ||
231 | } | ||
232 | |||
233 | fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", | ||
234 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); | ||
235 | |||
236 | /* Enable alarm interrupts */ | ||
237 | retval = ioctl(fd, RTC_AIE_ON, 0); | ||
238 | if (retval == -1) { | ||
239 | if (errno == EINVAL || errno == EIO) { | ||
240 | fprintf(stderr, | ||
241 | "\n...Alarm IRQs not supported.\n"); | ||
242 | goto test_PIE; | ||
243 | } | ||
244 | |||
245 | perror("RTC_AIE_ON ioctl"); | ||
246 | exit(errno); | ||
247 | } | ||
248 | |||
249 | fprintf(stderr, "Waiting 5 seconds for alarm..."); | ||
250 | fflush(stderr); | ||
251 | /* This blocks until the alarm ring causes an interrupt */ | ||
252 | retval = read(fd, &data, sizeof(unsigned long)); | ||
253 | if (retval == -1) { | ||
254 | perror("read"); | ||
255 | exit(errno); | ||
256 | } | ||
257 | irqcount++; | ||
258 | fprintf(stderr, " okay. Alarm rang.\n"); | ||
259 | |||
260 | /* Disable alarm interrupts */ | ||
261 | retval = ioctl(fd, RTC_AIE_OFF, 0); | ||
262 | if (retval == -1) { | ||
263 | perror("RTC_AIE_OFF ioctl"); | ||
264 | exit(errno); | ||
265 | } | ||
266 | |||
267 | test_PIE: | ||
268 | /* Read periodic IRQ rate */ | ||
269 | retval = ioctl(fd, RTC_IRQP_READ, &tmp); | ||
270 | if (retval == -1) { | ||
271 | /* not all RTCs support periodic IRQs */ | ||
272 | if (errno == EINVAL) { | ||
273 | fprintf(stderr, "\nNo periodic IRQ support\n"); | ||
274 | goto test_DATE; | ||
275 | } | ||
276 | perror("RTC_IRQP_READ ioctl"); | ||
277 | exit(errno); | ||
278 | } | ||
279 | fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); | ||
280 | |||
281 | fprintf(stderr, "Counting 20 interrupts at:"); | ||
282 | fflush(stderr); | ||
283 | |||
284 | /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ | ||
285 | for (tmp=2; tmp<=64; tmp*=2) { | ||
286 | |||
287 | retval = ioctl(fd, RTC_IRQP_SET, tmp); | ||
288 | if (retval == -1) { | ||
289 | /* not all RTCs can change their periodic IRQ rate */ | ||
290 | if (errno == EINVAL) { | ||
291 | fprintf(stderr, | ||
292 | "\n...Periodic IRQ rate is fixed\n"); | ||
293 | goto test_DATE; | ||
294 | } | ||
295 | perror("RTC_IRQP_SET ioctl"); | ||
296 | exit(errno); | ||
297 | } | ||
298 | |||
299 | fprintf(stderr, "\n%ldHz:\t", tmp); | ||
300 | fflush(stderr); | ||
301 | |||
302 | /* Enable periodic interrupts */ | ||
303 | retval = ioctl(fd, RTC_PIE_ON, 0); | ||
304 | if (retval == -1) { | ||
305 | perror("RTC_PIE_ON ioctl"); | ||
306 | exit(errno); | ||
307 | } | ||
308 | |||
309 | for (i=1; i<21; i++) { | ||
310 | gettimeofday(&start, NULL); | ||
311 | /* This blocks */ | ||
312 | retval = read(fd, &data, sizeof(unsigned long)); | ||
313 | if (retval == -1) { | ||
314 | perror("read"); | ||
315 | exit(errno); | ||
316 | } | ||
317 | gettimeofday(&end, NULL); | ||
318 | timersub(&end, &start, &diff); | ||
319 | if (diff.tv_sec > 0 || | ||
320 | diff.tv_usec > ((1000000L / tmp) * 1.10)) { | ||
321 | fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n", | ||
322 | diff.tv_sec, diff.tv_usec, | ||
323 | (1000000L / tmp)); | ||
324 | fflush(stdout); | ||
325 | exit(-1); | ||
326 | } | ||
327 | |||
328 | fprintf(stderr, " %d",i); | ||
329 | fflush(stderr); | ||
330 | irqcount++; | ||
331 | } | ||
332 | |||
333 | /* Disable periodic interrupts */ | ||
334 | retval = ioctl(fd, RTC_PIE_OFF, 0); | ||
335 | if (retval == -1) { | ||
336 | perror("RTC_PIE_OFF ioctl"); | ||
337 | exit(errno); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | test_DATE: | ||
342 | if (!dangerous) | ||
343 | goto done; | ||
344 | |||
345 | fprintf(stderr, "\nTesting problematic dates\n"); | ||
346 | |||
347 | for (i = 0; i < ARRAY_SIZE(cutoff_dates); i++) { | ||
348 | struct rtc_time current; | ||
349 | |||
350 | /* Write the new date in RTC */ | ||
351 | retval = ioctl(fd, RTC_SET_TIME, &cutoff_dates[i]); | ||
352 | if (retval == -1) { | ||
353 | perror("RTC_SET_TIME ioctl"); | ||
354 | close(fd); | ||
355 | exit(errno); | ||
356 | } | ||
357 | |||
358 | /* Read back */ | ||
359 | retval = ioctl(fd, RTC_RD_TIME, ¤t); | ||
360 | if (retval == -1) { | ||
361 | perror("RTC_RD_TIME ioctl"); | ||
362 | exit(errno); | ||
363 | } | ||
364 | |||
365 | if(compare_dates(&cutoff_dates[i], ¤t)) { | ||
366 | fprintf(stderr,"Setting date %d failed\n", | ||
367 | cutoff_dates[i].tm_year + 1900); | ||
368 | goto done; | ||
369 | } | ||
370 | |||
371 | cutoff_dates[i].tm_sec += 5; | ||
372 | |||
373 | /* Write the new alarm in RTC */ | ||
374 | retval = ioctl(fd, RTC_ALM_SET, &cutoff_dates[i]); | ||
375 | if (retval == -1) { | ||
376 | perror("RTC_ALM_SET ioctl"); | ||
377 | close(fd); | ||
378 | exit(errno); | ||
379 | } | ||
380 | |||
381 | /* Read back */ | ||
382 | retval = ioctl(fd, RTC_ALM_READ, ¤t); | ||
383 | if (retval == -1) { | ||
384 | perror("RTC_ALM_READ ioctl"); | ||
385 | exit(errno); | ||
386 | } | ||
387 | |||
388 | if(compare_dates(&cutoff_dates[i], ¤t)) { | ||
389 | fprintf(stderr,"Setting alarm %d failed\n", | ||
390 | cutoff_dates[i].tm_year + 1900); | ||
391 | goto done; | ||
392 | } | ||
393 | |||
394 | fprintf(stderr, "Setting year %d is OK \n", | ||
395 | cutoff_dates[i].tm_year + 1900); | ||
396 | } | ||
397 | done: | ||
398 | fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); | ||
399 | |||
400 | close(fd); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 39f66bc29b82..186520198de7 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
@@ -8,6 +8,7 @@ include ../lib.mk | |||
8 | UNAME_M := $(shell uname -m) | 8 | UNAME_M := $(shell uname -m) |
9 | CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) | 9 | CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) |
10 | CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) | 10 | CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) |
11 | CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh $(CC) trivial_program.c -no-pie) | ||
11 | 12 | ||
12 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ | 13 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ |
13 | check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ | 14 | check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ |
@@ -31,7 +32,12 @@ BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64) | |||
31 | BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) | 32 | BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) |
32 | BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) | 33 | BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) |
33 | 34 | ||
34 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -no-pie | 35 | CFLAGS := -O2 -g -std=gnu99 -pthread -Wall |
36 | |||
37 | # call32_from_64 in thunks.S uses absolute addresses. | ||
38 | ifeq ($(CAN_BUILD_WITH_NOPIE),1) | ||
39 | CFLAGS += -no-pie | ||
40 | endif | ||
35 | 41 | ||
36 | define gen-target-rule-32 | 42 | define gen-target-rule-32 |
37 | $(1) $(1)_32: $(OUTPUT)/$(1)_32 | 43 | $(1) $(1)_32: $(OUTPUT)/$(1)_32 |
diff --git a/tools/testing/selftests/x86/trivial_program.c b/tools/testing/selftests/x86/trivial_program.c new file mode 100644 index 000000000000..46a447163b93 --- /dev/null +++ b/tools/testing/selftests/x86/trivial_program.c | |||
@@ -0,0 +1,10 @@ | |||
1 | /* Trivial program to check that compilation with certain flags is working. */ | ||
2 | |||
3 | #include <stdio.h> | ||
4 | |||
5 | int | ||
6 | main(void) | ||
7 | { | ||
8 | puts(""); | ||
9 | return 0; | ||
10 | } | ||