diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-13 11:59:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-13 11:59:21 -0400 |
commit | 4541fec3104bef0c60633f9e180be94ea5ccc2b7 (patch) | |
tree | 8a2bb66c4510bf122ca414de22af0a6f98bc36ab /tools/testing | |
parent | 39a8804455fb23f09157341d3ba7db6d7ae6ee76 (diff) | |
parent | 2bfd4d1f8c2bee8b0b8832be0c38d3916713625f (diff) |
Merge tag 'linux-kselftest-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kselftest updates from Shuah Khan:
"This is a milestone update in a sense. Several new tests and install
and packaging support is added in this update.
This update adds install and packaging tools developed on top of
back-end shared logic enhancemnets to run and install tests. In
addition several timer tests are added.
- New timer tests from John Stultz
- rtc test from Prarit Bhargava
- Enhancements to un and install tests from Michael Ellerman
- Install and packaging tools from Shuah Khan
- Cross-compilation enablement from Tyler Baker
- A couple of bug fixes"
* tag 'linux-kselftest-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (42 commits)
ftracetest: Do not use usleep directly
selftest/mqueue: enable cross compilation
selftest/ipc: enable cross compilation
selftest/memfd: include default header install path
selftest/mount: enable cross compilation
selftest/memfd: enable cross compilation
kselftests: timers: Make set-timer-lat fail more gracefully for !CAP_WAKE_ALARM
selftests: Change memory on-off-test.sh name to be unique
selftests: change cpu on-off-test.sh name to be unique
selftests/mount: Make git ignore all binaries in mount test suite
kselftests: timers: Reduce default runtime on inconsistency-check and set-timer-lat
ftracetest: Convert exit -1 to exit $FAIL
ftracetest: Cope properly with stack tracer not being enabled
tools, update rtctest.c to verify passage of time
Documentation, split up rtc.txt into documentation and test file
selftests: Add tool to generate kselftest tar archive
selftests: Add kselftest install tool
selftests: Set CC using CROSS_COMPILE once in lib.mk
selftests: Add install support for the powerpc tests
selftests/timers: Use shared logic to run and install tests
...
Diffstat (limited to 'tools/testing')
67 files changed, 3364 insertions, 196 deletions
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 0db571340edb..d643d5242537 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile | |||
@@ -55,7 +55,40 @@ clean_hotplug: | |||
55 | make -C $$TARGET clean; \ | 55 | make -C $$TARGET clean; \ |
56 | done; | 56 | done; |
57 | 57 | ||
58 | INSTALL_PATH ?= install | ||
59 | INSTALL_PATH := $(abspath $(INSTALL_PATH)) | ||
60 | ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh | ||
61 | |||
62 | install: | ||
63 | ifdef INSTALL_PATH | ||
64 | @# Ask all targets to install their files | ||
65 | mkdir -p $(INSTALL_PATH) | ||
66 | for TARGET in $(TARGETS); do \ | ||
67 | mkdir -p $(INSTALL_PATH)/$$TARGET ; \ | ||
68 | make -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ | ||
69 | done; | ||
70 | |||
71 | @# Ask all targets to emit their test scripts | ||
72 | echo "#!/bin/bash" > $(ALL_SCRIPT) | ||
73 | echo "cd \$$(dirname \$$0)" >> $(ALL_SCRIPT) | ||
74 | echo "ROOT=\$$PWD" >> $(ALL_SCRIPT) | ||
75 | |||
76 | for TARGET in $(TARGETS); do \ | ||
77 | echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ | ||
78 | echo "echo ========================================" >> $(ALL_SCRIPT); \ | ||
79 | echo "cd $$TARGET" >> $(ALL_SCRIPT); \ | ||
80 | make -s --no-print-directory -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ | ||
81 | echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ | ||
82 | done; | ||
83 | |||
84 | chmod u+x $(ALL_SCRIPT) | ||
85 | else | ||
86 | $(error Error: set INSTALL_PATH to use install) | ||
87 | endif | ||
88 | |||
58 | clean: | 89 | clean: |
59 | for TARGET in $(TARGETS); do \ | 90 | for TARGET in $(TARGETS); do \ |
60 | make -C $$TARGET clean; \ | 91 | make -C $$TARGET clean; \ |
61 | done; | 92 | done; |
93 | |||
94 | .PHONY: install | ||
diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile index e18b42b254af..182235640209 100644 --- a/tools/testing/selftests/breakpoints/Makefile +++ b/tools/testing/selftests/breakpoints/Makefile | |||
@@ -16,8 +16,9 @@ else | |||
16 | echo "Not an x86 target, can't build breakpoints selftests" | 16 | echo "Not an x86 target, can't build breakpoints selftests" |
17 | endif | 17 | endif |
18 | 18 | ||
19 | run_tests: | 19 | TEST_PROGS := breakpoint_test |
20 | @./breakpoint_test || echo "breakpoints selftests: [FAIL]" | 20 | |
21 | include ../lib.mk | ||
21 | 22 | ||
22 | clean: | 23 | clean: |
23 | rm -fr breakpoint_test | 24 | rm -fr breakpoint_test |
diff --git a/tools/testing/selftests/cpu-hotplug/Makefile b/tools/testing/selftests/cpu-hotplug/Makefile index e9c28d8dc84b..fe1f99101c5d 100644 --- a/tools/testing/selftests/cpu-hotplug/Makefile +++ b/tools/testing/selftests/cpu-hotplug/Makefile | |||
@@ -1,9 +1,10 @@ | |||
1 | all: | 1 | all: |
2 | 2 | ||
3 | run_tests: | 3 | TEST_PROGS := cpu-on-off-test.sh |
4 | @/bin/bash ./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]" | 4 | |
5 | include ../lib.mk | ||
5 | 6 | ||
6 | run_full_test: | 7 | run_full_test: |
7 | @/bin/bash ./on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" | 8 | @/bin/bash ./cpu-on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" |
8 | 9 | ||
9 | clean: | 10 | clean: |
diff --git a/tools/testing/selftests/cpu-hotplug/on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh index 98b1d6565f2c..98b1d6565f2c 100644..100755 --- a/tools/testing/selftests/cpu-hotplug/on-off-test.sh +++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh | |||
diff --git a/tools/testing/selftests/efivarfs/Makefile b/tools/testing/selftests/efivarfs/Makefile index 29e8c6bc81b0..736c3ddfc787 100644 --- a/tools/testing/selftests/efivarfs/Makefile +++ b/tools/testing/selftests/efivarfs/Makefile | |||
@@ -1,12 +1,13 @@ | |||
1 | CC = $(CROSS_COMPILE)gcc | ||
2 | CFLAGS = -Wall | 1 | CFLAGS = -Wall |
3 | 2 | ||
4 | test_objs = open-unlink create-read | 3 | test_objs = open-unlink create-read |
5 | 4 | ||
6 | all: $(test_objs) | 5 | all: $(test_objs) |
7 | 6 | ||
8 | run_tests: all | 7 | TEST_PROGS := efivarfs.sh |
9 | @/bin/bash ./efivarfs.sh || echo "efivarfs selftests: [FAIL]" | 8 | TEST_FILES := $(test_objs) |
9 | |||
10 | include ../lib.mk | ||
10 | 11 | ||
11 | clean: | 12 | clean: |
12 | rm -f $(test_objs) | 13 | rm -f $(test_objs) |
diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh index 77edcdcc016b..77edcdcc016b 100644..100755 --- a/tools/testing/selftests/efivarfs/efivarfs.sh +++ b/tools/testing/selftests/efivarfs/efivarfs.sh | |||
diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index 66dfc2ce1788..4edb7d0da29b 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | CC = $(CROSS_COMPILE)gcc | ||
2 | CFLAGS = -Wall | 1 | CFLAGS = -Wall |
3 | BINARIES = execveat | 2 | BINARIES = execveat |
4 | DEPS = execveat.symlink execveat.denatured script subdir | 3 | DEPS = execveat.symlink execveat.denatured script subdir |
@@ -18,8 +17,12 @@ execveat.denatured: execveat | |||
18 | %: %.c | 17 | %: %.c |
19 | $(CC) $(CFLAGS) -o $@ $^ | 18 | $(CC) $(CFLAGS) -o $@ $^ |
20 | 19 | ||
21 | run_tests: all | 20 | TEST_PROGS := execveat |
22 | ./execveat | 21 | TEST_FILES := $(DEPS) |
22 | |||
23 | include ../lib.mk | ||
24 | |||
25 | override EMIT_TESTS := echo "mkdir -p subdir; (./execveat && echo \"selftests: execveat [PASS]\") || echo \"selftests: execveat [FAIL]\"" | ||
23 | 26 | ||
24 | clean: | 27 | clean: |
25 | rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx* | 28 | rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx* |
diff --git a/tools/testing/selftests/firmware/Makefile b/tools/testing/selftests/firmware/Makefile index e23cce0bbc3a..9bf82234855b 100644 --- a/tools/testing/selftests/firmware/Makefile +++ b/tools/testing/selftests/firmware/Makefile | |||
@@ -3,25 +3,9 @@ | |||
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 | fw_filesystem: | 6 | TEST_PROGS := fw_filesystem.sh fw_userhelper.sh |
7 | @if /bin/sh ./fw_filesystem.sh ; then \ | ||
8 | echo "fw_filesystem: ok"; \ | ||
9 | else \ | ||
10 | echo "fw_filesystem: [FAIL]"; \ | ||
11 | exit 1; \ | ||
12 | fi | ||
13 | 7 | ||
14 | fw_userhelper: | 8 | include ../lib.mk |
15 | @if /bin/sh ./fw_userhelper.sh ; then \ | ||
16 | echo "fw_userhelper: ok"; \ | ||
17 | else \ | ||
18 | echo "fw_userhelper: [FAIL]"; \ | ||
19 | exit 1; \ | ||
20 | fi | ||
21 | |||
22 | run_tests: all fw_filesystem fw_userhelper | ||
23 | 9 | ||
24 | # Nothing to clean up. | 10 | # Nothing to clean up. |
25 | clean: | 11 | clean: |
26 | |||
27 | .PHONY: all clean run_tests fw_filesystem fw_userhelper | ||
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh index 3fc6c10c2479..3fc6c10c2479 100644..100755 --- a/tools/testing/selftests/firmware/fw_filesystem.sh +++ b/tools/testing/selftests/firmware/fw_filesystem.sh | |||
diff --git a/tools/testing/selftests/firmware/fw_userhelper.sh b/tools/testing/selftests/firmware/fw_userhelper.sh index 6efbade12139..6efbade12139 100644..100755 --- a/tools/testing/selftests/firmware/fw_userhelper.sh +++ b/tools/testing/selftests/firmware/fw_userhelper.sh | |||
diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile index 76cc9f156267..346720639d1d 100644 --- a/tools/testing/selftests/ftrace/Makefile +++ b/tools/testing/selftests/ftrace/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | all: | 1 | all: |
2 | 2 | ||
3 | run_tests: | 3 | TEST_PROGS := ftracetest |
4 | @/bin/sh ./ftracetest || echo "ftrace selftests: [FAIL]" | 4 | |
5 | include ../lib.mk | ||
5 | 6 | ||
6 | clean: | 7 | clean: |
7 | rm -rf logs/* | 8 | rm -rf logs/* |
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc index fd9c49a13612..aa51f6c17359 100644 --- a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc +++ b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc | |||
@@ -2,4 +2,4 @@ | |||
2 | # description: Basic event tracing check | 2 | # description: Basic event tracing check |
3 | test -f available_events -a -f set_event -a -d events | 3 | test -f available_events -a -f set_event -a -d events |
4 | # check scheduler events are available | 4 | # check scheduler events are available |
5 | grep -q sched available_events && exit 0 || exit -1 \ No newline at end of file | 5 | grep -q sched available_events && exit 0 || exit $FAIL |
diff --git a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc index 668616d9bb03..87eb9d6dd4ca 100644 --- a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc | |||
@@ -9,7 +9,11 @@ do_reset() { | |||
9 | fail() { #msg | 9 | fail() { #msg |
10 | do_reset | 10 | do_reset |
11 | echo $1 | 11 | echo $1 |
12 | exit -1 | 12 | exit $FAIL |
13 | } | ||
14 | |||
15 | yield() { | ||
16 | ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 | ||
13 | } | 17 | } |
14 | 18 | ||
15 | if [ ! -f set_event -o ! -d events/sched ]; then | 19 | if [ ! -f set_event -o ! -d events/sched ]; then |
@@ -21,7 +25,8 @@ reset_tracer | |||
21 | do_reset | 25 | do_reset |
22 | 26 | ||
23 | echo 'sched:sched_switch' > set_event | 27 | echo 'sched:sched_switch' > set_event |
24 | usleep 1 | 28 | |
29 | yield | ||
25 | 30 | ||
26 | count=`cat trace | grep sched_switch | wc -l` | 31 | count=`cat trace | grep sched_switch | wc -l` |
27 | if [ $count -eq 0 ]; then | 32 | if [ $count -eq 0 ]; then |
@@ -31,7 +36,8 @@ fi | |||
31 | do_reset | 36 | do_reset |
32 | 37 | ||
33 | echo 1 > events/sched/sched_switch/enable | 38 | echo 1 > events/sched/sched_switch/enable |
34 | usleep 1 | 39 | |
40 | yield | ||
35 | 41 | ||
36 | count=`cat trace | grep sched_switch | wc -l` | 42 | count=`cat trace | grep sched_switch | wc -l` |
37 | if [ $count -eq 0 ]; then | 43 | if [ $count -eq 0 ]; then |
@@ -41,7 +47,8 @@ fi | |||
41 | do_reset | 47 | do_reset |
42 | 48 | ||
43 | echo 0 > events/sched/sched_switch/enable | 49 | echo 0 > events/sched/sched_switch/enable |
44 | usleep 1 | 50 | |
51 | yield | ||
45 | 52 | ||
46 | count=`cat trace | grep sched_switch | wc -l` | 53 | count=`cat trace | grep sched_switch | wc -l` |
47 | if [ $count -ne 0 ]; then | 54 | if [ $count -ne 0 ]; then |
diff --git a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc index 655c415b6e7f..ced27ef0638f 100644 --- a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc | |||
@@ -9,7 +9,11 @@ do_reset() { | |||
9 | fail() { #msg | 9 | fail() { #msg |
10 | do_reset | 10 | do_reset |
11 | echo $1 | 11 | echo $1 |
12 | exit -1 | 12 | exit $FAIL |
13 | } | ||
14 | |||
15 | yield() { | ||
16 | ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 | ||
13 | } | 17 | } |
14 | 18 | ||
15 | if [ ! -f set_event -o ! -d events/sched ]; then | 19 | if [ ! -f set_event -o ! -d events/sched ]; then |
@@ -21,7 +25,8 @@ reset_tracer | |||
21 | do_reset | 25 | do_reset |
22 | 26 | ||
23 | echo 'sched:*' > set_event | 27 | echo 'sched:*' > set_event |
24 | usleep 1 | 28 | |
29 | yield | ||
25 | 30 | ||
26 | count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` | 31 | count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` |
27 | if [ $count -lt 3 ]; then | 32 | if [ $count -lt 3 ]; then |
@@ -31,7 +36,8 @@ fi | |||
31 | do_reset | 36 | do_reset |
32 | 37 | ||
33 | echo 1 > events/sched/enable | 38 | echo 1 > events/sched/enable |
34 | usleep 1 | 39 | |
40 | yield | ||
35 | 41 | ||
36 | count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` | 42 | count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` |
37 | if [ $count -lt 3 ]; then | 43 | if [ $count -lt 3 ]; then |
@@ -41,7 +47,8 @@ fi | |||
41 | do_reset | 47 | do_reset |
42 | 48 | ||
43 | echo 0 > events/sched/enable | 49 | echo 0 > events/sched/enable |
44 | usleep 1 | 50 | |
51 | yield | ||
45 | 52 | ||
46 | count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` | 53 | count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` |
47 | if [ $count -ne 0 ]; then | 54 | if [ $count -ne 0 ]; then |
diff --git a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc index 480845774007..0bb5df3c00d4 100644 --- a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc | |||
@@ -9,7 +9,11 @@ do_reset() { | |||
9 | fail() { #msg | 9 | fail() { #msg |
10 | do_reset | 10 | do_reset |
11 | echo $1 | 11 | echo $1 |
12 | exit -1 | 12 | exit $FAIL |
13 | } | ||
14 | |||
15 | yield() { | ||
16 | ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 | ||
13 | } | 17 | } |
14 | 18 | ||
15 | if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then | 19 | if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then |
@@ -21,6 +25,9 @@ reset_tracer | |||
21 | do_reset | 25 | do_reset |
22 | 26 | ||
23 | echo '*:*' > set_event | 27 | echo '*:*' > set_event |
28 | |||
29 | yield | ||
30 | |||
24 | count=`cat trace | grep -v ^# | wc -l` | 31 | count=`cat trace | grep -v ^# | wc -l` |
25 | if [ $count -eq 0 ]; then | 32 | if [ $count -eq 0 ]; then |
26 | fail "none of events are recorded" | 33 | fail "none of events are recorded" |
@@ -29,6 +36,9 @@ fi | |||
29 | do_reset | 36 | do_reset |
30 | 37 | ||
31 | echo 1 > events/enable | 38 | echo 1 > events/enable |
39 | |||
40 | yield | ||
41 | |||
32 | count=`cat trace | grep -v ^# | wc -l` | 42 | count=`cat trace | grep -v ^# | wc -l` |
33 | if [ $count -eq 0 ]; then | 43 | if [ $count -eq 0 ]; then |
34 | fail "none of events are recorded" | 44 | fail "none of events are recorded" |
@@ -37,6 +47,9 @@ fi | |||
37 | do_reset | 47 | do_reset |
38 | 48 | ||
39 | echo 0 > events/enable | 49 | echo 0 > events/enable |
50 | |||
51 | yield | ||
52 | |||
40 | count=`cat trace | grep -v ^# | wc -l` | 53 | count=`cat trace | grep -v ^# | wc -l` |
41 | if [ $count -ne 0 ]; then | 54 | if [ $count -ne 0 ]; then |
42 | fail "any of events should not be recorded" | 55 | fail "any of events should not be recorded" |
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc index c15e018e0220..15c2dba06ea2 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc | |||
@@ -16,7 +16,9 @@ fi | |||
16 | 16 | ||
17 | do_reset() { | 17 | do_reset() { |
18 | reset_tracer | 18 | reset_tracer |
19 | echo 0 > /proc/sys/kernel/stack_tracer_enabled | 19 | if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then |
20 | echo 0 > /proc/sys/kernel/stack_tracer_enabled | ||
21 | fi | ||
20 | enable_tracing | 22 | enable_tracing |
21 | clear_trace | 23 | clear_trace |
22 | echo > set_ftrace_filter | 24 | echo > set_ftrace_filter |
@@ -25,7 +27,7 @@ do_reset() { | |||
25 | fail() { # msg | 27 | fail() { # msg |
26 | do_reset | 28 | do_reset |
27 | echo $1 | 29 | echo $1 |
28 | exit -1 | 30 | exit $FAIL |
29 | } | 31 | } |
30 | 32 | ||
31 | disable_tracing | 33 | disable_tracing |
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc index 6af5f6360b18..0ab2189613ef 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc | |||
@@ -17,7 +17,7 @@ do_reset() { | |||
17 | fail() { # msg | 17 | fail() { # msg |
18 | do_reset | 18 | do_reset |
19 | echo $1 | 19 | echo $1 |
20 | exit -1 | 20 | exit $FAIL |
21 | } | 21 | } |
22 | 22 | ||
23 | disable_tracing | 23 | disable_tracing |
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc index 2e719cb1fc4d..7808336d6f50 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc | |||
@@ -31,7 +31,7 @@ fail() { # mesg | |||
31 | reset_tracer | 31 | reset_tracer |
32 | echo > set_ftrace_filter | 32 | echo > set_ftrace_filter |
33 | echo $1 | 33 | echo $1 |
34 | exit -1 | 34 | exit $FAIL |
35 | } | 35 | } |
36 | 36 | ||
37 | echo "Testing function tracer with profiler:" | 37 | echo "Testing function tracer with profiler:" |
diff --git a/tools/testing/selftests/gen_kselftest_tar.sh b/tools/testing/selftests/gen_kselftest_tar.sh new file mode 100755 index 000000000000..17d5bd0c0936 --- /dev/null +++ b/tools/testing/selftests/gen_kselftest_tar.sh | |||
@@ -0,0 +1,55 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # gen_kselftest_tar | ||
4 | # Generate kselftest tarball | ||
5 | # Author: Shuah Khan <shuahkh@osg.samsung.com> | ||
6 | # Copyright (C) 2015 Samsung Electronics Co., Ltd. | ||
7 | |||
8 | # This software may be freely redistributed under the terms of the GNU | ||
9 | # General Public License (GPLv2). | ||
10 | |||
11 | # main | ||
12 | main() | ||
13 | { | ||
14 | if [ "$#" -eq 0 ]; then | ||
15 | echo "$0: Generating default compression gzip" | ||
16 | copts="cvzf" | ||
17 | ext=".tar.gz" | ||
18 | else | ||
19 | case "$1" in | ||
20 | tar) | ||
21 | copts="cvf" | ||
22 | ext=".tar" | ||
23 | ;; | ||
24 | targz) | ||
25 | copts="cvzf" | ||
26 | ext=".tar.gz" | ||
27 | ;; | ||
28 | tarbz2) | ||
29 | copts="cvjf" | ||
30 | ext=".tar.bz2" | ||
31 | ;; | ||
32 | tarxz) | ||
33 | copts="cvJf" | ||
34 | ext=".tar.xz" | ||
35 | ;; | ||
36 | *) | ||
37 | echo "Unknown tarball format $1" | ||
38 | exit 1 | ||
39 | ;; | ||
40 | esac | ||
41 | fi | ||
42 | |||
43 | install_dir=./kselftest | ||
44 | |||
45 | # Run install using INSTALL_KSFT_PATH override to generate install | ||
46 | # directory | ||
47 | ./kselftest_install.sh | ||
48 | tar $copts kselftest${ext} $install_dir | ||
49 | echo "Kselftest archive kselftest${ext} created!" | ||
50 | |||
51 | # clean up install directory | ||
52 | rm -rf kselftest | ||
53 | } | ||
54 | |||
55 | main "$@" | ||
diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile index 74bbefdeaf4c..25d2e702c68a 100644 --- a/tools/testing/selftests/ipc/Makefile +++ b/tools/testing/selftests/ipc/Makefile | |||
@@ -12,14 +12,11 @@ endif | |||
12 | CFLAGS += -I../../../../usr/include/ | 12 | CFLAGS += -I../../../../usr/include/ |
13 | 13 | ||
14 | all: | 14 | all: |
15 | ifeq ($(ARCH),x86) | 15 | $(CC) $(CFLAGS) msgque.c -o msgque_test |
16 | gcc $(CFLAGS) msgque.c -o msgque_test | 16 | |
17 | else | 17 | TEST_PROGS := msgque_test |
18 | echo "Not an x86 target, can't build msgque selftest" | ||
19 | endif | ||
20 | 18 | ||
21 | run_tests: all | 19 | include ../lib.mk |
22 | ./msgque_test | ||
23 | 20 | ||
24 | clean: | 21 | clean: |
25 | rm -fr ./msgque_test | 22 | rm -fr ./msgque_test |
diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile index ff0eefdc6ceb..2ae7450a9a89 100644 --- a/tools/testing/selftests/kcmp/Makefile +++ b/tools/testing/selftests/kcmp/Makefile | |||
@@ -1,10 +1,10 @@ | |||
1 | CC := $(CROSS_COMPILE)$(CC) | ||
2 | CFLAGS += -I../../../../usr/include/ | 1 | CFLAGS += -I../../../../usr/include/ |
3 | 2 | ||
4 | all: kcmp_test | 3 | all: kcmp_test |
5 | 4 | ||
6 | run_tests: all | 5 | TEST_PROGS := kcmp_test |
7 | @./kcmp_test || echo "kcmp_test: [FAIL]" | 6 | |
7 | include ../lib.mk | ||
8 | 8 | ||
9 | clean: | 9 | clean: |
10 | $(RM) kcmp_test kcmp-test-file | 10 | $(RM) kcmp_test kcmp-test-file |
diff --git a/tools/testing/selftests/kselftest_install.sh b/tools/testing/selftests/kselftest_install.sh new file mode 100755 index 000000000000..1555fbdb08da --- /dev/null +++ b/tools/testing/selftests/kselftest_install.sh | |||
@@ -0,0 +1,37 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # Kselftest Install | ||
4 | # Install kselftest tests | ||
5 | # Author: Shuah Khan <shuahkh@osg.samsung.com> | ||
6 | # Copyright (C) 2015 Samsung Electronics Co., Ltd. | ||
7 | |||
8 | # This software may be freely redistributed under the terms of the GNU | ||
9 | # General Public License (GPLv2). | ||
10 | |||
11 | install_loc=`pwd` | ||
12 | |||
13 | main() | ||
14 | { | ||
15 | if [ $(basename $install_loc) != "selftests" ]; then | ||
16 | echo "$0: Please run it in selftests directory ..." | ||
17 | exit 1; | ||
18 | fi | ||
19 | if [ "$#" -eq 0 ]; then | ||
20 | echo "$0: Installing in default location - $install_loc ..." | ||
21 | elif [ ! -d "$1" ]; then | ||
22 | echo "$0: $1 doesn't exist!!" | ||
23 | exit 1; | ||
24 | else | ||
25 | install_loc=$1 | ||
26 | echo "$0: Installing in specified location - $install_loc ..." | ||
27 | fi | ||
28 | |||
29 | install_dir=$install_loc/kselftest | ||
30 | |||
31 | # Create install directory | ||
32 | mkdir -p $install_dir | ||
33 | # Build tests | ||
34 | INSTALL_PATH=$install_dir make install | ||
35 | } | ||
36 | |||
37 | main "$@" | ||
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk new file mode 100644 index 000000000000..2194155ae62a --- /dev/null +++ b/tools/testing/selftests/lib.mk | |||
@@ -0,0 +1,35 @@ | |||
1 | # This mimics the top-level Makefile. We do it explicitly here so that this | ||
2 | # Makefile can operate with or without the kbuild infrastructure. | ||
3 | CC := $(CROSS_COMPILE)gcc | ||
4 | |||
5 | define RUN_TESTS | ||
6 | @for TEST in $(TEST_PROGS); do \ | ||
7 | (./$$TEST && echo "selftests: $$TEST [PASS]") || echo "selftests: $$TEST [FAIL]"; \ | ||
8 | done; | ||
9 | endef | ||
10 | |||
11 | run_tests: all | ||
12 | $(RUN_TESTS) | ||
13 | |||
14 | define INSTALL_RULE | ||
15 | mkdir -p $(INSTALL_PATH) | ||
16 | install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) | ||
17 | endef | ||
18 | |||
19 | install: all | ||
20 | ifdef INSTALL_PATH | ||
21 | $(INSTALL_RULE) | ||
22 | else | ||
23 | $(error Error: set INSTALL_PATH to use install) | ||
24 | endif | ||
25 | |||
26 | define EMIT_TESTS | ||
27 | @for TEST in $(TEST_PROGS); do \ | ||
28 | echo "(./$$TEST && echo \"selftests: $$TEST [PASS]\") || echo \"selftests: $$TEST [FAIL]\""; \ | ||
29 | done; | ||
30 | endef | ||
31 | |||
32 | emit_tests: | ||
33 | $(EMIT_TESTS) | ||
34 | |||
35 | .PHONY: run_tests all clean install emit_tests | ||
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index b80cd10d53ba..3e7eb7972511 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile | |||
@@ -1,17 +1,19 @@ | |||
1 | CC = $(CROSS_COMPILE)gcc | ||
1 | CFLAGS += -D_FILE_OFFSET_BITS=64 | 2 | CFLAGS += -D_FILE_OFFSET_BITS=64 |
2 | CFLAGS += -I../../../../include/uapi/ | 3 | CFLAGS += -I../../../../include/uapi/ |
3 | CFLAGS += -I../../../../include/ | 4 | CFLAGS += -I../../../../include/ |
5 | CFLAGS += -I../../../../usr/include/ | ||
4 | 6 | ||
5 | all: | 7 | all: |
6 | gcc $(CFLAGS) memfd_test.c -o memfd_test | 8 | $(CC) $(CFLAGS) memfd_test.c -o memfd_test |
7 | 9 | ||
8 | run_tests: all | 10 | TEST_PROGS := memfd_test |
9 | gcc $(CFLAGS) memfd_test.c -o memfd_test | 11 | |
10 | @./memfd_test || echo "memfd_test: [FAIL]" | 12 | include ../lib.mk |
11 | 13 | ||
12 | build_fuse: | 14 | build_fuse: |
13 | gcc $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt | 15 | $(CC) $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt |
14 | gcc $(CFLAGS) fuse_test.c -o fuse_test | 16 | $(CC) $(CFLAGS) fuse_test.c -o fuse_test |
15 | 17 | ||
16 | run_fuse: build_fuse | 18 | run_fuse: build_fuse |
17 | @./run_fuse_test.sh || echo "fuse_test: [FAIL]" | 19 | @./run_fuse_test.sh || echo "fuse_test: [FAIL]" |
diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile index d46b8d489cd2..afb2624c7048 100644 --- a/tools/testing/selftests/memory-hotplug/Makefile +++ b/tools/testing/selftests/memory-hotplug/Makefile | |||
@@ -1,9 +1,12 @@ | |||
1 | all: | 1 | all: |
2 | 2 | ||
3 | run_tests: | 3 | include ../lib.mk |
4 | @/bin/bash ./on-off-test.sh -r 2 || echo "memory-hotplug selftests: [FAIL]" | 4 | |
5 | TEST_PROGS := mem-on-off-test.sh | ||
6 | override RUN_TESTS := ./mem-on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]" | ||
7 | override EMIT_TESTS := echo "$(RUN_TESTS)" | ||
5 | 8 | ||
6 | run_full_test: | 9 | run_full_test: |
7 | @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" | 10 | @/bin/bash ./mem-on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" |
8 | 11 | ||
9 | clean: | 12 | clean: |
diff --git a/tools/testing/selftests/memory-hotplug/on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh index 6cddde0b96f8..6cddde0b96f8 100644..100755 --- a/tools/testing/selftests/memory-hotplug/on-off-test.sh +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh | |||
diff --git a/tools/testing/selftests/mount/.gitignore b/tools/testing/selftests/mount/.gitignore new file mode 100644 index 000000000000..856ad4107eb3 --- /dev/null +++ b/tools/testing/selftests/mount/.gitignore | |||
@@ -0,0 +1 @@ | |||
unprivileged-remount-test | |||
diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile index 337d853c2b72..95580a97326e 100644 --- a/tools/testing/selftests/mount/Makefile +++ b/tools/testing/selftests/mount/Makefile | |||
@@ -1,17 +1,16 @@ | |||
1 | # Makefile for mount selftests. | 1 | # Makefile for mount selftests. |
2 | 2 | CFLAGS = -Wall \ | |
3 | -O2 | ||
3 | all: unprivileged-remount-test | 4 | all: unprivileged-remount-test |
4 | 5 | ||
5 | unprivileged-remount-test: unprivileged-remount-test.c | 6 | unprivileged-remount-test: unprivileged-remount-test.c |
6 | gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test | 7 | $(CC) $(CFLAGS) unprivileged-remount-test.c -o unprivileged-remount-test |
7 | 8 | ||
8 | # Allow specific tests to be selected. | 9 | include ../lib.mk |
9 | test_unprivileged_remount: unprivileged-remount-test | ||
10 | @if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi | ||
11 | 10 | ||
12 | run_tests: all test_unprivileged_remount | 11 | TEST_PROGS := unprivileged-remount-test |
12 | override RUN_TESTS := if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi | ||
13 | override EMIT_TESTS := echo "$(RUN_TESTS)" | ||
13 | 14 | ||
14 | clean: | 15 | clean: |
15 | rm -f unprivileged-remount-test | 16 | rm -f unprivileged-remount-test |
16 | |||
17 | .PHONY: all test_unprivileged_remount | ||
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile index 8056e2e68fa4..0e3b41eb85cd 100644 --- a/tools/testing/selftests/mqueue/Makefile +++ b/tools/testing/selftests/mqueue/Makefile | |||
@@ -1,10 +1,22 @@ | |||
1 | CFLAGS = -O2 | ||
2 | |||
1 | all: | 3 | all: |
2 | gcc -O2 mq_open_tests.c -o mq_open_tests -lrt | 4 | $(CC) $(CFLAGS) mq_open_tests.c -o mq_open_tests -lrt |
3 | gcc -O2 -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt | 5 | $(CC) $(CFLAGS) -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt |
6 | |||
7 | include ../lib.mk | ||
8 | |||
9 | override define RUN_TESTS | ||
10 | @./mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]" | ||
11 | @./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" | ||
12 | endef | ||
13 | |||
14 | TEST_PROGS := mq_open_tests mq_perf_tests | ||
4 | 15 | ||
5 | run_tests: | 16 | override define EMIT_TESTS |
6 | @./mq_open_tests /test1 || echo "mq_open_tests: [FAIL]" | 17 | echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\"" |
7 | @./mq_perf_tests || echo "mq_perf_tests: [FAIL]" | 18 | echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\"" |
19 | endef | ||
8 | 20 | ||
9 | clean: | 21 | clean: |
10 | rm -f mq_open_tests mq_perf_tests | 22 | rm -f mq_open_tests mq_perf_tests |
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 62f22cc9941c..fac4782c51d8 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | # Makefile for net selftests | 1 | # Makefile for net selftests |
2 | 2 | ||
3 | CC = $(CROSS_COMPILE)gcc | ||
4 | CFLAGS = -Wall -O2 -g | 3 | CFLAGS = -Wall -O2 -g |
5 | 4 | ||
6 | CFLAGS += -I../../../../usr/include/ | 5 | CFLAGS += -I../../../../usr/include/ |
@@ -11,9 +10,10 @@ all: $(NET_PROGS) | |||
11 | %: %.c | 10 | %: %.c |
12 | $(CC) $(CFLAGS) -o $@ $^ | 11 | $(CC) $(CFLAGS) -o $@ $^ |
13 | 12 | ||
14 | run_tests: all | 13 | TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh |
15 | @/bin/sh ./run_netsocktests || echo "sockettests: [FAIL]" | 14 | TEST_FILES := $(NET_PROGS) |
16 | @/bin/sh ./run_afpackettests || echo "afpackettests: [FAIL]" | 15 | |
17 | ./test_bpf.sh | 16 | include ../lib.mk |
17 | |||
18 | clean: | 18 | clean: |
19 | $(RM) $(NET_PROGS) | 19 | $(RM) $(NET_PROGS) |
diff --git a/tools/testing/selftests/net/run_afpackettests b/tools/testing/selftests/net/run_afpackettests index 5246e782d6e8..5246e782d6e8 100644..100755 --- a/tools/testing/selftests/net/run_afpackettests +++ b/tools/testing/selftests/net/run_afpackettests | |||
diff --git a/tools/testing/selftests/net/run_netsocktests b/tools/testing/selftests/net/run_netsocktests index c09a682df56a..c09a682df56a 100644..100755 --- a/tools/testing/selftests/net/run_netsocktests +++ b/tools/testing/selftests/net/run_netsocktests | |||
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 1d5e7ad2c460..2958fe9a74e9 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -8,10 +8,9 @@ ifeq ($(ARCH),powerpc) | |||
8 | 8 | ||
9 | GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") | 9 | GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") |
10 | 10 | ||
11 | CC := $(CROSS_COMPILE)$(CC) | ||
12 | CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) | 11 | CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) |
13 | 12 | ||
14 | export CC CFLAGS | 13 | export CFLAGS |
15 | 14 | ||
16 | TARGETS = pmu copyloops mm tm primitives stringloops | 15 | TARGETS = pmu copyloops mm tm primitives stringloops |
17 | 16 | ||
@@ -22,10 +21,25 @@ all: $(TARGETS) | |||
22 | $(TARGETS): | 21 | $(TARGETS): |
23 | $(MAKE) -k -C $@ all | 22 | $(MAKE) -k -C $@ all |
24 | 23 | ||
25 | run_tests: all | 24 | include ../lib.mk |
25 | |||
26 | override define RUN_TESTS | ||
26 | @for TARGET in $(TARGETS); do \ | 27 | @for TARGET in $(TARGETS); do \ |
27 | $(MAKE) -C $$TARGET run_tests; \ | 28 | $(MAKE) -C $$TARGET run_tests; \ |
28 | done; | 29 | done; |
30 | endef | ||
31 | |||
32 | override define INSTALL_RULE | ||
33 | @for TARGET in $(TARGETS); do \ | ||
34 | $(MAKE) -C $$TARGET install; \ | ||
35 | done; | ||
36 | endef | ||
37 | |||
38 | override define EMIT_TESTS | ||
39 | @for TARGET in $(TARGETS); do \ | ||
40 | $(MAKE) -s -C $$TARGET emit_tests; \ | ||
41 | done; | ||
42 | endef | ||
29 | 43 | ||
30 | clean: | 44 | clean: |
31 | @for TARGET in $(TARGETS); do \ | 45 | @for TARGET in $(TARGETS); do \ |
@@ -36,4 +50,4 @@ clean: | |||
36 | tags: | 50 | tags: |
37 | find . -name '*.c' -o -name '*.h' | xargs ctags | 51 | find . -name '*.c' -o -name '*.h' | xargs ctags |
38 | 52 | ||
39 | .PHONY: all run_tests clean tags $(TARGETS) | 53 | .PHONY: tags $(TARGETS) |
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile index 6f2d3be227f9..c05023514ce8 100644 --- a/tools/testing/selftests/powerpc/copyloops/Makefile +++ b/tools/testing/selftests/powerpc/copyloops/Makefile | |||
@@ -6,24 +6,19 @@ CFLAGS += -D SELFTEST | |||
6 | # Use our CFLAGS for the implicit .S rule | 6 | # Use our CFLAGS for the implicit .S rule |
7 | ASFLAGS = $(CFLAGS) | 7 | ASFLAGS = $(CFLAGS) |
8 | 8 | ||
9 | PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 | 9 | TEST_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 |
10 | EXTRA_SOURCES := validate.c ../harness.c | 10 | EXTRA_SOURCES := validate.c ../harness.c |
11 | 11 | ||
12 | all: $(PROGS) | 12 | all: $(TEST_PROGS) |
13 | 13 | ||
14 | copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base | 14 | copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base |
15 | copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 | 15 | copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 |
16 | memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy | 16 | memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy |
17 | memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 | 17 | memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 |
18 | 18 | ||
19 | $(PROGS): $(EXTRA_SOURCES) | 19 | $(TEST_PROGS): $(EXTRA_SOURCES) |
20 | 20 | ||
21 | run_tests: all | 21 | include ../../lib.mk |
22 | @-for PROG in $(PROGS); do \ | ||
23 | ./$$PROG; \ | ||
24 | done; | ||
25 | 22 | ||
26 | clean: | 23 | clean: |
27 | rm -f $(PROGS) *.o | 24 | rm -f $(TEST_PROGS) *.o |
28 | |||
29 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile index a14c538dd7f8..41cc3ed66818 100644 --- a/tools/testing/selftests/powerpc/mm/Makefile +++ b/tools/testing/selftests/powerpc/mm/Makefile | |||
@@ -1,21 +1,16 @@ | |||
1 | noarg: | 1 | noarg: |
2 | $(MAKE) -C ../ | 2 | $(MAKE) -C ../ |
3 | 3 | ||
4 | PROGS := hugetlb_vs_thp_test subpage_prot | 4 | TEST_PROGS := hugetlb_vs_thp_test subpage_prot |
5 | 5 | ||
6 | all: $(PROGS) tempfile | 6 | all: $(TEST_PROGS) tempfile |
7 | 7 | ||
8 | $(PROGS): ../harness.c | 8 | $(TEST_PROGS): ../harness.c |
9 | 9 | ||
10 | run_tests: all | 10 | include ../../lib.mk |
11 | @-for PROG in $(PROGS); do \ | ||
12 | ./$$PROG; \ | ||
13 | done; | ||
14 | 11 | ||
15 | tempfile: | 12 | tempfile: |
16 | dd if=/dev/zero of=tempfile bs=64k count=1 | 13 | dd if=/dev/zero of=tempfile bs=64k count=1 |
17 | 14 | ||
18 | clean: | 15 | clean: |
19 | rm -f $(PROGS) tempfile | 16 | rm -f $(TEST_PROGS) tempfile |
20 | |||
21 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index c9f4263906a5..5a161175bbd4 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile | |||
@@ -1,38 +1,42 @@ | |||
1 | noarg: | 1 | noarg: |
2 | $(MAKE) -C ../ | 2 | $(MAKE) -C ../ |
3 | 3 | ||
4 | PROGS := count_instructions l3_bank_test per_event_excludes | 4 | TEST_PROGS := count_instructions l3_bank_test per_event_excludes |
5 | EXTRA_SOURCES := ../harness.c event.c lib.c | 5 | EXTRA_SOURCES := ../harness.c event.c lib.c |
6 | 6 | ||
7 | SUB_TARGETS = ebb | 7 | all: $(TEST_PROGS) ebb |
8 | 8 | ||
9 | all: $(PROGS) $(SUB_TARGETS) | 9 | $(TEST_PROGS): $(EXTRA_SOURCES) |
10 | |||
11 | $(PROGS): $(EXTRA_SOURCES) | ||
12 | 10 | ||
13 | # loop.S can only be built 64-bit | 11 | # loop.S can only be built 64-bit |
14 | count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) | 12 | count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) |
15 | $(CC) $(CFLAGS) -m64 -o $@ $^ | 13 | $(CC) $(CFLAGS) -m64 -o $@ $^ |
16 | 14 | ||
17 | run_tests: all sub_run_tests | 15 | include ../../lib.mk |
18 | @-for PROG in $(PROGS); do \ | ||
19 | ./$$PROG; \ | ||
20 | done; | ||
21 | 16 | ||
22 | clean: sub_clean | 17 | DEFAULT_RUN_TESTS := $(RUN_TESTS) |
23 | rm -f $(PROGS) loop.o | 18 | override define RUN_TESTS |
19 | $(DEFAULT_RUN_TESTS) | ||
20 | $(MAKE) -C ebb run_tests | ||
21 | endef | ||
24 | 22 | ||
25 | $(SUB_TARGETS): | 23 | DEFAULT_EMIT_TESTS := $(EMIT_TESTS) |
26 | $(MAKE) -k -C $@ all | 24 | override define EMIT_TESTS |
25 | $(DEFAULT_EMIT_TESTS) | ||
26 | $(MAKE) -s -C ebb emit_tests | ||
27 | endef | ||
27 | 28 | ||
28 | sub_run_tests: all | 29 | DEFAULT_INSTALL := $(INSTALL_RULE) |
29 | @for TARGET in $(SUB_TARGETS); do \ | 30 | override define INSTALL_RULE |
30 | $(MAKE) -C $$TARGET run_tests; \ | 31 | $(DEFAULT_INSTALL_RULE) |
31 | done; | 32 | $(MAKE) -C ebb install |
33 | endef | ||
32 | 34 | ||
33 | sub_clean: | 35 | clean: |
34 | @for TARGET in $(SUB_TARGETS); do \ | 36 | rm -f $(TEST_PROGS) loop.o |
35 | $(MAKE) -C $$TARGET clean; \ | 37 | $(MAKE) -C ebb clean |
36 | done; | 38 | |
39 | ebb: | ||
40 | $(MAKE) -k -C $@ all | ||
37 | 41 | ||
38 | .PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS) | 42 | .PHONY: all run_tests clean ebb |
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile index 3dc4332698cb..5cdc9dbf2b27 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile +++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile | |||
@@ -4,7 +4,7 @@ noarg: | |||
4 | # The EBB handler is 64-bit code and everything links against it | 4 | # The EBB handler is 64-bit code and everything links against it |
5 | CFLAGS += -m64 | 5 | CFLAGS += -m64 |
6 | 6 | ||
7 | PROGS := reg_access_test event_attributes_test cycles_test \ | 7 | TEST_PROGS := reg_access_test event_attributes_test cycles_test \ |
8 | cycles_with_freeze_test pmc56_overflow_test \ | 8 | cycles_with_freeze_test pmc56_overflow_test \ |
9 | ebb_vs_cpu_event_test cpu_event_vs_ebb_test \ | 9 | ebb_vs_cpu_event_test cpu_event_vs_ebb_test \ |
10 | cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \ | 10 | cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \ |
@@ -16,18 +16,15 @@ PROGS := reg_access_test event_attributes_test cycles_test \ | |||
16 | lost_exception_test no_handler_test \ | 16 | lost_exception_test no_handler_test \ |
17 | cycles_with_mmcr2_test | 17 | cycles_with_mmcr2_test |
18 | 18 | ||
19 | all: $(PROGS) | 19 | all: $(TEST_PROGS) |
20 | 20 | ||
21 | $(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S | 21 | $(TEST_PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S |
22 | 22 | ||
23 | instruction_count_test: ../loop.S | 23 | instruction_count_test: ../loop.S |
24 | 24 | ||
25 | lost_exception_test: ../lib.c | 25 | lost_exception_test: ../lib.c |
26 | 26 | ||
27 | run_tests: all | 27 | include ../../../lib.mk |
28 | @-for PROG in $(PROGS); do \ | ||
29 | ./$$PROG; \ | ||
30 | done; | ||
31 | 28 | ||
32 | clean: | 29 | clean: |
33 | rm -f $(PROGS) | 30 | rm -f $(TEST_PROGS) |
diff --git a/tools/testing/selftests/powerpc/primitives/Makefile b/tools/testing/selftests/powerpc/primitives/Makefile index ea737ca01732..b68c6221d3d1 100644 --- a/tools/testing/selftests/powerpc/primitives/Makefile +++ b/tools/testing/selftests/powerpc/primitives/Makefile | |||
@@ -1,17 +1,12 @@ | |||
1 | CFLAGS += -I$(CURDIR) | 1 | CFLAGS += -I$(CURDIR) |
2 | 2 | ||
3 | PROGS := load_unaligned_zeropad | 3 | TEST_PROGS := load_unaligned_zeropad |
4 | 4 | ||
5 | all: $(PROGS) | 5 | all: $(TEST_PROGS) |
6 | 6 | ||
7 | $(PROGS): ../harness.c | 7 | $(TEST_PROGS): ../harness.c |
8 | 8 | ||
9 | run_tests: all | 9 | include ../../lib.mk |
10 | @-for PROG in $(PROGS); do \ | ||
11 | ./$$PROG; \ | ||
12 | done; | ||
13 | 10 | ||
14 | clean: | 11 | clean: |
15 | rm -f $(PROGS) *.o | 12 | rm -f $(TEST_PROGS) *.o |
16 | |||
17 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile index 506d77346477..2a728f4d2873 100644 --- a/tools/testing/selftests/powerpc/stringloops/Makefile +++ b/tools/testing/selftests/powerpc/stringloops/Makefile | |||
@@ -2,19 +2,14 @@ | |||
2 | CFLAGS += -m64 | 2 | CFLAGS += -m64 |
3 | CFLAGS += -I$(CURDIR) | 3 | CFLAGS += -I$(CURDIR) |
4 | 4 | ||
5 | PROGS := memcmp | 5 | TEST_PROGS := memcmp |
6 | EXTRA_SOURCES := memcmp_64.S ../harness.c | 6 | EXTRA_SOURCES := memcmp_64.S ../harness.c |
7 | 7 | ||
8 | all: $(PROGS) | 8 | all: $(TEST_PROGS) |
9 | 9 | ||
10 | $(PROGS): $(EXTRA_SOURCES) | 10 | $(TEST_PROGS): $(EXTRA_SOURCES) |
11 | 11 | ||
12 | run_tests: all | 12 | include ../../lib.mk |
13 | @-for PROG in $(PROGS); do \ | ||
14 | ./$$PROG; \ | ||
15 | done; | ||
16 | 13 | ||
17 | clean: | 14 | clean: |
18 | rm -f $(PROGS) *.o | 15 | rm -f $(TEST_PROGS) *.o |
19 | |||
20 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 2cede239a074..34f2ec634b40 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile | |||
@@ -1,15 +1,10 @@ | |||
1 | PROGS := tm-resched-dscr | 1 | TEST_PROGS := tm-resched-dscr |
2 | 2 | ||
3 | all: $(PROGS) | 3 | all: $(TEST_PROGS) |
4 | 4 | ||
5 | $(PROGS): ../harness.c | 5 | $(TEST_PROGS): ../harness.c |
6 | 6 | ||
7 | run_tests: all | 7 | include ../../lib.mk |
8 | @-for PROG in $(PROGS); do \ | ||
9 | ./$$PROG; \ | ||
10 | done; | ||
11 | 8 | ||
12 | clean: | 9 | clean: |
13 | rm -f $(PROGS) *.o | 10 | rm -f $(TEST_PROGS) *.o |
14 | |||
15 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/ptrace/Makefile b/tools/testing/selftests/ptrace/Makefile index 47ae2d385ce8..453927fea90c 100644 --- a/tools/testing/selftests/ptrace/Makefile +++ b/tools/testing/selftests/ptrace/Makefile | |||
@@ -6,5 +6,6 @@ all: peeksiginfo | |||
6 | clean: | 6 | clean: |
7 | rm -f peeksiginfo | 7 | rm -f peeksiginfo |
8 | 8 | ||
9 | run_tests: all | 9 | TEST_PROGS := peeksiginfo |
10 | @./peeksiginfo || echo "peeksiginfo selftests: [FAIL]" | 10 | |
11 | include ../lib.mk | ||
diff --git a/tools/testing/selftests/size/Makefile b/tools/testing/selftests/size/Makefile index 04dc25e4fa92..bbd0b5398b61 100644 --- a/tools/testing/selftests/size/Makefile +++ b/tools/testing/selftests/size/Makefile | |||
@@ -1,12 +1,11 @@ | |||
1 | CC = $(CROSS_COMPILE)gcc | ||
2 | |||
3 | all: get_size | 1 | all: get_size |
4 | 2 | ||
5 | get_size: get_size.c | 3 | get_size: get_size.c |
6 | $(CC) -static -ffreestanding -nostartfiles -s $< -o $@ | 4 | $(CC) -static -ffreestanding -nostartfiles -s $< -o $@ |
7 | 5 | ||
8 | run_tests: all | 6 | TEST_PROGS := get_size |
9 | ./get_size | 7 | |
8 | include ../lib.mk | ||
10 | 9 | ||
11 | clean: | 10 | clean: |
12 | $(RM) get_size | 11 | $(RM) get_size |
diff --git a/tools/testing/selftests/sysctl/Makefile b/tools/testing/selftests/sysctl/Makefile index 0a92adaf0865..b3c33e071f10 100644 --- a/tools/testing/selftests/sysctl/Makefile +++ b/tools/testing/selftests/sysctl/Makefile | |||
@@ -4,16 +4,10 @@ | |||
4 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests". | 4 | # No binaries, but make sure arg-less "make" doesn't trigger "run_tests". |
5 | all: | 5 | all: |
6 | 6 | ||
7 | # Allow specific tests to be selected. | 7 | TEST_PROGS := run_numerictests run_stringtests |
8 | test_num: | 8 | TEST_FILES := common_tests |
9 | @/bin/sh ./run_numerictests | ||
10 | 9 | ||
11 | test_string: | 10 | include ../lib.mk |
12 | @/bin/sh ./run_stringtests | ||
13 | |||
14 | run_tests: all test_num test_string | ||
15 | 11 | ||
16 | # Nothing to clean up. | 12 | # Nothing to clean up. |
17 | clean: | 13 | clean: |
18 | |||
19 | .PHONY: all run_tests clean test_num test_string | ||
diff --git a/tools/testing/selftests/sysctl/run_numerictests b/tools/testing/selftests/sysctl/run_numerictests index 8510f93f2d14..8510f93f2d14 100644..100755 --- a/tools/testing/selftests/sysctl/run_numerictests +++ b/tools/testing/selftests/sysctl/run_numerictests | |||
diff --git a/tools/testing/selftests/sysctl/run_stringtests b/tools/testing/selftests/sysctl/run_stringtests index 90a9293d520c..90a9293d520c 100644..100755 --- a/tools/testing/selftests/sysctl/run_stringtests +++ b/tools/testing/selftests/sysctl/run_stringtests | |||
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index eb2859f4ad21..89a3f44bf355 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile | |||
@@ -1,8 +1,36 @@ | |||
1 | all: | 1 | CC = $(CROSS_COMPILE)gcc |
2 | gcc posix_timers.c -o posix_timers -lrt | 2 | BUILD_FLAGS = -DKTEST |
3 | CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) | ||
4 | LDFLAGS += -lrt -lpthread | ||
3 | 5 | ||
4 | run_tests: all | 6 | # these are all "safe" tests that don't modify |
5 | ./posix_timers | 7 | # system time or require escalated privledges |
8 | TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ | ||
9 | inconsistency-check raw_skew threadtest rtctest | ||
10 | |||
11 | TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex change_skew \ | ||
12 | skew_consistency clocksource-switch leap-a-day \ | ||
13 | leapcrash set-tai set-2038 | ||
14 | |||
15 | bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED) | ||
16 | |||
17 | all: ${bins} | ||
18 | |||
19 | include ../lib.mk | ||
20 | |||
21 | # these tests require escalated privledges | ||
22 | # and may modify the system time or trigger | ||
23 | # other behavior like suspend | ||
24 | run_destructive_tests: run_tests | ||
25 | ./alarmtimer-suspend | ||
26 | ./valid-adjtimex | ||
27 | ./change_skew | ||
28 | ./skew_consistency | ||
29 | ./clocksource-switch | ||
30 | ./leap-a-day -s -i 10 | ||
31 | ./leapcrash | ||
32 | ./set-tai | ||
33 | ./set-2038 | ||
6 | 34 | ||
7 | clean: | 35 | clean: |
8 | rm -f ./posix_timers | 36 | rm -f ${bins} |
diff --git a/tools/testing/selftests/timers/alarmtimer-suspend.c b/tools/testing/selftests/timers/alarmtimer-suspend.c new file mode 100644 index 000000000000..aaffbde1d5ee --- /dev/null +++ b/tools/testing/selftests/timers/alarmtimer-suspend.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* alarmtimer suspend test | ||
2 | * John Stultz (john.stultz@linaro.org) | ||
3 | * (C) Copyright Linaro 2013 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * This test makes sure the alarmtimer & RTC wakeup code is | ||
7 | * functioning. | ||
8 | * | ||
9 | * To build: | ||
10 | * $ gcc alarmtimer-suspend.c -o alarmtimer-suspend -lrt | ||
11 | * | ||
12 | * This program is free software: you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation, either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <unistd.h> | ||
26 | #include <time.h> | ||
27 | #include <string.h> | ||
28 | #include <signal.h> | ||
29 | #include <stdlib.h> | ||
30 | #include <pthread.h> | ||
31 | #ifdef KTEST | ||
32 | #include "../kselftest.h" | ||
33 | #else | ||
34 | static inline int ksft_exit_pass(void) | ||
35 | { | ||
36 | exit(0); | ||
37 | } | ||
38 | static inline int ksft_exit_fail(void) | ||
39 | { | ||
40 | exit(1); | ||
41 | } | ||
42 | #endif | ||
43 | |||
44 | #define CLOCK_REALTIME 0 | ||
45 | #define CLOCK_MONOTONIC 1 | ||
46 | #define CLOCK_PROCESS_CPUTIME_ID 2 | ||
47 | #define CLOCK_THREAD_CPUTIME_ID 3 | ||
48 | #define CLOCK_MONOTONIC_RAW 4 | ||
49 | #define CLOCK_REALTIME_COARSE 5 | ||
50 | #define CLOCK_MONOTONIC_COARSE 6 | ||
51 | #define CLOCK_BOOTTIME 7 | ||
52 | #define CLOCK_REALTIME_ALARM 8 | ||
53 | #define CLOCK_BOOTTIME_ALARM 9 | ||
54 | #define CLOCK_HWSPECIFIC 10 | ||
55 | #define CLOCK_TAI 11 | ||
56 | #define NR_CLOCKIDS 12 | ||
57 | |||
58 | |||
59 | #define NSEC_PER_SEC 1000000000ULL | ||
60 | #define UNREASONABLE_LAT (NSEC_PER_SEC * 4) /* hopefully we resume in 4secs */ | ||
61 | |||
62 | #define SUSPEND_SECS 15 | ||
63 | int alarmcount; | ||
64 | int alarm_clock_id; | ||
65 | struct timespec start_time; | ||
66 | |||
67 | |||
68 | char *clockstring(int clockid) | ||
69 | { | ||
70 | switch (clockid) { | ||
71 | case CLOCK_REALTIME: | ||
72 | return "CLOCK_REALTIME"; | ||
73 | case CLOCK_MONOTONIC: | ||
74 | return "CLOCK_MONOTONIC"; | ||
75 | case CLOCK_PROCESS_CPUTIME_ID: | ||
76 | return "CLOCK_PROCESS_CPUTIME_ID"; | ||
77 | case CLOCK_THREAD_CPUTIME_ID: | ||
78 | return "CLOCK_THREAD_CPUTIME_ID"; | ||
79 | case CLOCK_MONOTONIC_RAW: | ||
80 | return "CLOCK_MONOTONIC_RAW"; | ||
81 | case CLOCK_REALTIME_COARSE: | ||
82 | return "CLOCK_REALTIME_COARSE"; | ||
83 | case CLOCK_MONOTONIC_COARSE: | ||
84 | return "CLOCK_MONOTONIC_COARSE"; | ||
85 | case CLOCK_BOOTTIME: | ||
86 | return "CLOCK_BOOTTIME"; | ||
87 | case CLOCK_REALTIME_ALARM: | ||
88 | return "CLOCK_REALTIME_ALARM"; | ||
89 | case CLOCK_BOOTTIME_ALARM: | ||
90 | return "CLOCK_BOOTTIME_ALARM"; | ||
91 | case CLOCK_TAI: | ||
92 | return "CLOCK_TAI"; | ||
93 | }; | ||
94 | return "UNKNOWN_CLOCKID"; | ||
95 | } | ||
96 | |||
97 | |||
98 | long long timespec_sub(struct timespec a, struct timespec b) | ||
99 | { | ||
100 | long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; | ||
101 | |||
102 | ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | int final_ret = 0; | ||
107 | |||
108 | void sigalarm(int signo) | ||
109 | { | ||
110 | long long delta_ns; | ||
111 | struct timespec ts; | ||
112 | |||
113 | clock_gettime(alarm_clock_id, &ts); | ||
114 | alarmcount++; | ||
115 | |||
116 | delta_ns = timespec_sub(start_time, ts); | ||
117 | delta_ns -= NSEC_PER_SEC * SUSPEND_SECS * alarmcount; | ||
118 | |||
119 | printf("ALARM(%i): %ld:%ld latency: %lld ns ", alarmcount, ts.tv_sec, | ||
120 | ts.tv_nsec, delta_ns); | ||
121 | |||
122 | if (delta_ns > UNREASONABLE_LAT) { | ||
123 | printf("[FAIL]\n"); | ||
124 | final_ret = -1; | ||
125 | } else | ||
126 | printf("[OK]\n"); | ||
127 | |||
128 | } | ||
129 | |||
130 | int main(void) | ||
131 | { | ||
132 | timer_t tm1; | ||
133 | struct itimerspec its1, its2; | ||
134 | struct sigevent se; | ||
135 | struct sigaction act; | ||
136 | int signum = SIGRTMAX; | ||
137 | |||
138 | /* Set up signal handler: */ | ||
139 | sigfillset(&act.sa_mask); | ||
140 | act.sa_flags = 0; | ||
141 | act.sa_handler = sigalarm; | ||
142 | sigaction(signum, &act, NULL); | ||
143 | |||
144 | /* Set up timer: */ | ||
145 | memset(&se, 0, sizeof(se)); | ||
146 | se.sigev_notify = SIGEV_SIGNAL; | ||
147 | se.sigev_signo = signum; | ||
148 | se.sigev_value.sival_int = 0; | ||
149 | |||
150 | for (alarm_clock_id = CLOCK_REALTIME_ALARM; | ||
151 | alarm_clock_id <= CLOCK_BOOTTIME_ALARM; | ||
152 | alarm_clock_id++) { | ||
153 | |||
154 | alarmcount = 0; | ||
155 | timer_create(alarm_clock_id, &se, &tm1); | ||
156 | |||
157 | clock_gettime(alarm_clock_id, &start_time); | ||
158 | printf("Start time (%s): %ld:%ld\n", clockstring(alarm_clock_id), | ||
159 | start_time.tv_sec, start_time.tv_nsec); | ||
160 | printf("Setting alarm for every %i seconds\n", SUSPEND_SECS); | ||
161 | its1.it_value = start_time; | ||
162 | its1.it_value.tv_sec += SUSPEND_SECS; | ||
163 | its1.it_interval.tv_sec = SUSPEND_SECS; | ||
164 | its1.it_interval.tv_nsec = 0; | ||
165 | |||
166 | timer_settime(tm1, TIMER_ABSTIME, &its1, &its2); | ||
167 | |||
168 | while (alarmcount < 5) | ||
169 | sleep(1); /* First 5 alarms, do nothing */ | ||
170 | |||
171 | printf("Starting suspend loops\n"); | ||
172 | while (alarmcount < 10) { | ||
173 | int ret; | ||
174 | |||
175 | sleep(1); | ||
176 | ret = system("echo mem > /sys/power/state"); | ||
177 | if (ret) | ||
178 | break; | ||
179 | } | ||
180 | timer_delete(tm1); | ||
181 | } | ||
182 | if (final_ret) | ||
183 | return ksft_exit_fail(); | ||
184 | return ksft_exit_pass(); | ||
185 | } | ||
diff --git a/tools/testing/selftests/timers/change_skew.c b/tools/testing/selftests/timers/change_skew.c new file mode 100644 index 000000000000..cb1968977c04 --- /dev/null +++ b/tools/testing/selftests/timers/change_skew.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* ADJ_FREQ Skew change test | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * (C) Copyright IBM 2012 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * NOTE: This is a meta-test which cranks the ADJ_FREQ knob and | ||
7 | * then uses other tests to detect problems. Thus this test requires | ||
8 | * that the raw_skew, inconsistency-check and nanosleep tests be | ||
9 | * present in the same directory it is run from. | ||
10 | * | ||
11 | * To build: | ||
12 | * $ gcc change_skew.c -o change_skew -lrt | ||
13 | * | ||
14 | * This program is free software: you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation, either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <sys/time.h> | ||
29 | #include <sys/timex.h> | ||
30 | #include <time.h> | ||
31 | #ifdef KTEST | ||
32 | #include "../kselftest.h" | ||
33 | #else | ||
34 | static inline int ksft_exit_pass(void) | ||
35 | { | ||
36 | exit(0); | ||
37 | } | ||
38 | static inline int ksft_exit_fail(void) | ||
39 | { | ||
40 | exit(1); | ||
41 | } | ||
42 | #endif | ||
43 | |||
44 | #define NSEC_PER_SEC 1000000000LL | ||
45 | |||
46 | |||
47 | int change_skew_test(int ppm) | ||
48 | { | ||
49 | struct timex tx; | ||
50 | int ret; | ||
51 | |||
52 | tx.modes = ADJ_FREQUENCY; | ||
53 | tx.freq = ppm << 16; | ||
54 | |||
55 | ret = adjtimex(&tx); | ||
56 | if (ret < 0) { | ||
57 | printf("Error adjusting freq\n"); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | ret = system("./raw_skew"); | ||
62 | ret |= system("./inconsistency-check"); | ||
63 | ret |= system("./nanosleep"); | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | |||
69 | int main(int argv, char **argc) | ||
70 | { | ||
71 | struct timex tx; | ||
72 | int i, ret; | ||
73 | |||
74 | int ppm[5] = {0, 250, 500, -250, -500}; | ||
75 | |||
76 | /* Kill ntpd */ | ||
77 | ret = system("killall -9 ntpd"); | ||
78 | |||
79 | /* Make sure there's no offset adjustment going on */ | ||
80 | tx.modes = ADJ_OFFSET; | ||
81 | tx.offset = 0; | ||
82 | ret = adjtimex(&tx); | ||
83 | |||
84 | if (ret < 0) { | ||
85 | printf("Maybe you're not running as root?\n"); | ||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | for (i = 0; i < 5; i++) { | ||
90 | printf("Using %i ppm adjustment\n", ppm[i]); | ||
91 | ret = change_skew_test(ppm[i]); | ||
92 | if (ret) | ||
93 | break; | ||
94 | } | ||
95 | |||
96 | /* Set things back */ | ||
97 | tx.modes = ADJ_FREQUENCY; | ||
98 | tx.offset = 0; | ||
99 | adjtimex(&tx); | ||
100 | |||
101 | if (ret) { | ||
102 | printf("[FAIL]"); | ||
103 | return ksft_exit_fail(); | ||
104 | } | ||
105 | printf("[OK]"); | ||
106 | return ksft_exit_pass(); | ||
107 | } | ||
diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c new file mode 100644 index 000000000000..627ec7425f78 --- /dev/null +++ b/tools/testing/selftests/timers/clocksource-switch.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* Clocksource change test | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * (C) Copyright IBM 2012 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * NOTE: This is a meta-test which quickly changes the clocksourc and | ||
7 | * then uses other tests to detect problems. Thus this test requires | ||
8 | * that the inconsistency-check and nanosleep tests be present in the | ||
9 | * same directory it is run from. | ||
10 | * | ||
11 | * To build: | ||
12 | * $ gcc clocksource-switch.c -o clocksource-switch -lrt | ||
13 | * | ||
14 | * This program is free software: you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation, either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <unistd.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <sys/time.h> | ||
30 | #include <sys/timex.h> | ||
31 | #include <time.h> | ||
32 | #include <sys/types.h> | ||
33 | #include <sys/stat.h> | ||
34 | #include <fcntl.h> | ||
35 | #include <string.h> | ||
36 | #include <sys/wait.h> | ||
37 | #ifdef KTEST | ||
38 | #include "../kselftest.h" | ||
39 | #else | ||
40 | static inline int ksft_exit_pass(void) | ||
41 | { | ||
42 | exit(0); | ||
43 | } | ||
44 | static inline int ksft_exit_fail(void) | ||
45 | { | ||
46 | exit(1); | ||
47 | } | ||
48 | #endif | ||
49 | |||
50 | |||
51 | int get_clocksources(char list[][30]) | ||
52 | { | ||
53 | int fd, i; | ||
54 | size_t size; | ||
55 | char buf[512]; | ||
56 | char *head, *tmp; | ||
57 | |||
58 | fd = open("/sys/devices/system/clocksource/clocksource0/available_clocksource", O_RDONLY); | ||
59 | |||
60 | size = read(fd, buf, 512); | ||
61 | |||
62 | close(fd); | ||
63 | |||
64 | for (i = 0; i < 30; i++) | ||
65 | list[i][0] = '\0'; | ||
66 | |||
67 | head = buf; | ||
68 | i = 0; | ||
69 | while (head - buf < size) { | ||
70 | /* Find the next space */ | ||
71 | for (tmp = head; *tmp != ' '; tmp++) { | ||
72 | if (*tmp == '\n') | ||
73 | break; | ||
74 | if (*tmp == '\0') | ||
75 | break; | ||
76 | } | ||
77 | *tmp = '\0'; | ||
78 | strcpy(list[i], head); | ||
79 | head = tmp + 1; | ||
80 | i++; | ||
81 | } | ||
82 | |||
83 | return i-1; | ||
84 | } | ||
85 | |||
86 | int get_cur_clocksource(char *buf, size_t size) | ||
87 | { | ||
88 | int fd; | ||
89 | |||
90 | fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_RDONLY); | ||
91 | |||
92 | size = read(fd, buf, size); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | int change_clocksource(char *clocksource) | ||
98 | { | ||
99 | int fd; | ||
100 | size_t size; | ||
101 | |||
102 | fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY); | ||
103 | |||
104 | if (fd < 0) | ||
105 | return -1; | ||
106 | |||
107 | size = write(fd, clocksource, strlen(clocksource)); | ||
108 | |||
109 | if (size < 0) | ||
110 | return -1; | ||
111 | |||
112 | close(fd); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | |||
117 | int run_tests(int secs) | ||
118 | { | ||
119 | int ret; | ||
120 | char buf[255]; | ||
121 | |||
122 | sprintf(buf, "./inconsistency-check -t %i", secs); | ||
123 | ret = system(buf); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | ret = system("./nanosleep"); | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | |||
131 | char clocksource_list[10][30]; | ||
132 | |||
133 | int main(int argv, char **argc) | ||
134 | { | ||
135 | char orig_clk[512]; | ||
136 | int count, i, status; | ||
137 | pid_t pid; | ||
138 | |||
139 | get_cur_clocksource(orig_clk, 512); | ||
140 | |||
141 | count = get_clocksources(clocksource_list); | ||
142 | |||
143 | if (change_clocksource(clocksource_list[0])) { | ||
144 | printf("Error: You probably need to run this as root\n"); | ||
145 | return -1; | ||
146 | } | ||
147 | |||
148 | /* Check everything is sane before we start switching asyncrhonously */ | ||
149 | for (i = 0; i < count; i++) { | ||
150 | printf("Validating clocksource %s\n", clocksource_list[i]); | ||
151 | if (change_clocksource(clocksource_list[i])) { | ||
152 | status = -1; | ||
153 | goto out; | ||
154 | } | ||
155 | if (run_tests(5)) { | ||
156 | status = -1; | ||
157 | goto out; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | |||
162 | printf("Running Asyncrhonous Switching Tests...\n"); | ||
163 | pid = fork(); | ||
164 | if (!pid) | ||
165 | return run_tests(60); | ||
166 | |||
167 | while (pid != waitpid(pid, &status, WNOHANG)) | ||
168 | for (i = 0; i < count; i++) | ||
169 | if (change_clocksource(clocksource_list[i])) { | ||
170 | status = -1; | ||
171 | goto out; | ||
172 | } | ||
173 | out: | ||
174 | change_clocksource(orig_clk); | ||
175 | |||
176 | if (status) | ||
177 | return ksft_exit_fail(); | ||
178 | return ksft_exit_pass(); | ||
179 | } | ||
diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c new file mode 100644 index 000000000000..caf1bc9257c4 --- /dev/null +++ b/tools/testing/selftests/timers/inconsistency-check.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* Time inconsistency check test | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * (C) Copyright IBM 2003, 2004, 2005, 2012 | ||
4 | * (C) Copyright Linaro Limited 2015 | ||
5 | * Licensed under the GPLv2 | ||
6 | * | ||
7 | * To build: | ||
8 | * $ gcc inconsistency-check.c -o inconsistency-check -lrt | ||
9 | * | ||
10 | * This program is free software: you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation, either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | |||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <unistd.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <time.h> | ||
27 | #include <sys/time.h> | ||
28 | #include <sys/timex.h> | ||
29 | #include <string.h> | ||
30 | #include <signal.h> | ||
31 | #ifdef KTEST | ||
32 | #include "../kselftest.h" | ||
33 | #else | ||
34 | static inline int ksft_exit_pass(void) | ||
35 | { | ||
36 | exit(0); | ||
37 | } | ||
38 | static inline int ksft_exit_fail(void) | ||
39 | { | ||
40 | exit(1); | ||
41 | } | ||
42 | #endif | ||
43 | |||
44 | #define CALLS_PER_LOOP 64 | ||
45 | #define NSEC_PER_SEC 1000000000ULL | ||
46 | |||
47 | #define CLOCK_REALTIME 0 | ||
48 | #define CLOCK_MONOTONIC 1 | ||
49 | #define CLOCK_PROCESS_CPUTIME_ID 2 | ||
50 | #define CLOCK_THREAD_CPUTIME_ID 3 | ||
51 | #define CLOCK_MONOTONIC_RAW 4 | ||
52 | #define CLOCK_REALTIME_COARSE 5 | ||
53 | #define CLOCK_MONOTONIC_COARSE 6 | ||
54 | #define CLOCK_BOOTTIME 7 | ||
55 | #define CLOCK_REALTIME_ALARM 8 | ||
56 | #define CLOCK_BOOTTIME_ALARM 9 | ||
57 | #define CLOCK_HWSPECIFIC 10 | ||
58 | #define CLOCK_TAI 11 | ||
59 | #define NR_CLOCKIDS 12 | ||
60 | |||
61 | char *clockstring(int clockid) | ||
62 | { | ||
63 | switch (clockid) { | ||
64 | case CLOCK_REALTIME: | ||
65 | return "CLOCK_REALTIME"; | ||
66 | case CLOCK_MONOTONIC: | ||
67 | return "CLOCK_MONOTONIC"; | ||
68 | case CLOCK_PROCESS_CPUTIME_ID: | ||
69 | return "CLOCK_PROCESS_CPUTIME_ID"; | ||
70 | case CLOCK_THREAD_CPUTIME_ID: | ||
71 | return "CLOCK_THREAD_CPUTIME_ID"; | ||
72 | case CLOCK_MONOTONIC_RAW: | ||
73 | return "CLOCK_MONOTONIC_RAW"; | ||
74 | case CLOCK_REALTIME_COARSE: | ||
75 | return "CLOCK_REALTIME_COARSE"; | ||
76 | case CLOCK_MONOTONIC_COARSE: | ||
77 | return "CLOCK_MONOTONIC_COARSE"; | ||
78 | case CLOCK_BOOTTIME: | ||
79 | return "CLOCK_BOOTTIME"; | ||
80 | case CLOCK_REALTIME_ALARM: | ||
81 | return "CLOCK_REALTIME_ALARM"; | ||
82 | case CLOCK_BOOTTIME_ALARM: | ||
83 | return "CLOCK_BOOTTIME_ALARM"; | ||
84 | case CLOCK_TAI: | ||
85 | return "CLOCK_TAI"; | ||
86 | }; | ||
87 | return "UNKNOWN_CLOCKID"; | ||
88 | } | ||
89 | |||
90 | /* returns 1 if a <= b, 0 otherwise */ | ||
91 | static inline int in_order(struct timespec a, struct timespec b) | ||
92 | { | ||
93 | /* use unsigned to avoid false positives on 2038 rollover */ | ||
94 | if ((unsigned long)a.tv_sec < (unsigned long)b.tv_sec) | ||
95 | return 1; | ||
96 | if ((unsigned long)a.tv_sec > (unsigned long)b.tv_sec) | ||
97 | return 0; | ||
98 | if (a.tv_nsec > b.tv_nsec) | ||
99 | return 0; | ||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | |||
104 | |||
105 | int consistency_test(int clock_type, unsigned long seconds) | ||
106 | { | ||
107 | struct timespec list[CALLS_PER_LOOP]; | ||
108 | int i, inconsistent; | ||
109 | long now, then; | ||
110 | time_t t; | ||
111 | char *start_str; | ||
112 | |||
113 | clock_gettime(clock_type, &list[0]); | ||
114 | now = then = list[0].tv_sec; | ||
115 | |||
116 | /* timestamp start of test */ | ||
117 | t = time(0); | ||
118 | start_str = ctime(&t); | ||
119 | |||
120 | while (seconds == -1 || now - then < seconds) { | ||
121 | inconsistent = 0; | ||
122 | |||
123 | /* Fill list */ | ||
124 | for (i = 0; i < CALLS_PER_LOOP; i++) | ||
125 | clock_gettime(clock_type, &list[i]); | ||
126 | |||
127 | /* Check for inconsistencies */ | ||
128 | for (i = 0; i < CALLS_PER_LOOP - 1; i++) | ||
129 | if (!in_order(list[i], list[i+1])) | ||
130 | inconsistent = i; | ||
131 | |||
132 | /* display inconsistency */ | ||
133 | if (inconsistent) { | ||
134 | unsigned long long delta; | ||
135 | |||
136 | printf("\%s\n", start_str); | ||
137 | for (i = 0; i < CALLS_PER_LOOP; i++) { | ||
138 | if (i == inconsistent) | ||
139 | printf("--------------------\n"); | ||
140 | printf("%lu:%lu\n", list[i].tv_sec, | ||
141 | list[i].tv_nsec); | ||
142 | if (i == inconsistent + 1) | ||
143 | printf("--------------------\n"); | ||
144 | } | ||
145 | delta = list[inconsistent].tv_sec * NSEC_PER_SEC; | ||
146 | delta += list[inconsistent].tv_nsec; | ||
147 | delta -= list[inconsistent+1].tv_sec * NSEC_PER_SEC; | ||
148 | delta -= list[inconsistent+1].tv_nsec; | ||
149 | printf("Delta: %llu ns\n", delta); | ||
150 | fflush(0); | ||
151 | /* timestamp inconsistency*/ | ||
152 | t = time(0); | ||
153 | printf("%s\n", ctime(&t)); | ||
154 | printf("[FAILED]\n"); | ||
155 | return -1; | ||
156 | } | ||
157 | now = list[0].tv_sec; | ||
158 | } | ||
159 | printf("[OK]\n"); | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | |||
164 | int main(int argc, char *argv[]) | ||
165 | { | ||
166 | int clockid, opt; | ||
167 | int userclock = CLOCK_REALTIME; | ||
168 | int maxclocks = NR_CLOCKIDS; | ||
169 | int runtime = 10; | ||
170 | struct timespec ts; | ||
171 | |||
172 | /* Process arguments */ | ||
173 | while ((opt = getopt(argc, argv, "t:c:")) != -1) { | ||
174 | switch (opt) { | ||
175 | case 't': | ||
176 | runtime = atoi(optarg); | ||
177 | break; | ||
178 | case 'c': | ||
179 | userclock = atoi(optarg); | ||
180 | maxclocks = userclock + 1; | ||
181 | break; | ||
182 | default: | ||
183 | printf("Usage: %s [-t <secs>] [-c <clockid>]\n", argv[0]); | ||
184 | printf(" -t: Number of seconds to run\n"); | ||
185 | printf(" -c: clockid to use (default, all clockids)\n"); | ||
186 | exit(-1); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | setbuf(stdout, NULL); | ||
191 | |||
192 | for (clockid = userclock; clockid < maxclocks; clockid++) { | ||
193 | |||
194 | if (clockid == CLOCK_HWSPECIFIC) | ||
195 | continue; | ||
196 | |||
197 | if (!clock_gettime(clockid, &ts)) { | ||
198 | printf("Consistent %-30s ", clockstring(clockid)); | ||
199 | if (consistency_test(clockid, runtime)) | ||
200 | return ksft_exit_fail(); | ||
201 | } | ||
202 | } | ||
203 | return ksft_exit_pass(); | ||
204 | } | ||
diff --git a/tools/testing/selftests/timers/leap-a-day.c b/tools/testing/selftests/timers/leap-a-day.c new file mode 100644 index 000000000000..b8272e6c4b3b --- /dev/null +++ b/tools/testing/selftests/timers/leap-a-day.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* Leap second stress test | ||
2 | * by: John Stultz (john.stultz@linaro.org) | ||
3 | * (C) Copyright IBM 2012 | ||
4 | * (C) Copyright 2013, 2015 Linaro Limited | ||
5 | * Licensed under the GPLv2 | ||
6 | * | ||
7 | * This test signals the kernel to insert a leap second | ||
8 | * every day at midnight GMT. This allows for stessing the | ||
9 | * kernel's leap-second behavior, as well as how well applications | ||
10 | * handle the leap-second discontinuity. | ||
11 | * | ||
12 | * Usage: leap-a-day [-s] [-i <num>] | ||
13 | * | ||
14 | * Options: | ||
15 | * -s: Each iteration, set the date to 10 seconds before midnight GMT. | ||
16 | * This speeds up the number of leapsecond transitions tested, | ||
17 | * but because it calls settimeofday frequently, advancing the | ||
18 | * time by 24 hours every ~16 seconds, it may cause application | ||
19 | * disruption. | ||
20 | * | ||
21 | * -i: Number of iterations to run (default: infinite) | ||
22 | * | ||
23 | * Other notes: Disabling NTP prior to running this is advised, as the two | ||
24 | * may conflict in their commands to the kernel. | ||
25 | * | ||
26 | * To build: | ||
27 | * $ gcc leap-a-day.c -o leap-a-day -lrt | ||
28 | * | ||
29 | * This program is free software: you can redistribute it and/or modify | ||
30 | * it under the terms of the GNU General Public License as published by | ||
31 | * the Free Software Foundation, either version 2 of the License, or | ||
32 | * (at your option) any later version. | ||
33 | * | ||
34 | * This program is distributed in the hope that it will be useful, | ||
35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
37 | * GNU General Public License for more details. | ||
38 | */ | ||
39 | |||
40 | |||
41 | |||
42 | #include <stdio.h> | ||
43 | #include <stdlib.h> | ||
44 | #include <time.h> | ||
45 | #include <sys/time.h> | ||
46 | #include <sys/timex.h> | ||
47 | #include <string.h> | ||
48 | #include <signal.h> | ||
49 | #include <unistd.h> | ||
50 | #ifdef KTEST | ||
51 | #include "../kselftest.h" | ||
52 | #else | ||
53 | static inline int ksft_exit_pass(void) | ||
54 | { | ||
55 | exit(0); | ||
56 | } | ||
57 | static inline int ksft_exit_fail(void) | ||
58 | { | ||
59 | exit(1); | ||
60 | } | ||
61 | #endif | ||
62 | |||
63 | #define NSEC_PER_SEC 1000000000ULL | ||
64 | #define CLOCK_TAI 11 | ||
65 | |||
66 | /* returns 1 if a <= b, 0 otherwise */ | ||
67 | static inline int in_order(struct timespec a, struct timespec b) | ||
68 | { | ||
69 | if (a.tv_sec < b.tv_sec) | ||
70 | return 1; | ||
71 | if (a.tv_sec > b.tv_sec) | ||
72 | return 0; | ||
73 | if (a.tv_nsec > b.tv_nsec) | ||
74 | return 0; | ||
75 | return 1; | ||
76 | } | ||
77 | |||
78 | struct timespec timespec_add(struct timespec ts, unsigned long long ns) | ||
79 | { | ||
80 | ts.tv_nsec += ns; | ||
81 | while (ts.tv_nsec >= NSEC_PER_SEC) { | ||
82 | ts.tv_nsec -= NSEC_PER_SEC; | ||
83 | ts.tv_sec++; | ||
84 | } | ||
85 | return ts; | ||
86 | } | ||
87 | |||
88 | char *time_state_str(int state) | ||
89 | { | ||
90 | switch (state) { | ||
91 | case TIME_OK: return "TIME_OK"; | ||
92 | case TIME_INS: return "TIME_INS"; | ||
93 | case TIME_DEL: return "TIME_DEL"; | ||
94 | case TIME_OOP: return "TIME_OOP"; | ||
95 | case TIME_WAIT: return "TIME_WAIT"; | ||
96 | case TIME_BAD: return "TIME_BAD"; | ||
97 | } | ||
98 | return "ERROR"; | ||
99 | } | ||
100 | |||
101 | /* clear NTP time_status & time_state */ | ||
102 | int clear_time_state(void) | ||
103 | { | ||
104 | struct timex tx; | ||
105 | int ret; | ||
106 | |||
107 | /* | ||
108 | * We have to call adjtime twice here, as kernels | ||
109 | * prior to 6b1859dba01c7 (included in 3.5 and | ||
110 | * -stable), had an issue with the state machine | ||
111 | * and wouldn't clear the STA_INS/DEL flag directly. | ||
112 | */ | ||
113 | tx.modes = ADJ_STATUS; | ||
114 | tx.status = STA_PLL; | ||
115 | ret = adjtimex(&tx); | ||
116 | |||
117 | /* Clear maxerror, as it can cause UNSYNC to be set */ | ||
118 | tx.modes = ADJ_MAXERROR; | ||
119 | tx.maxerror = 0; | ||
120 | ret = adjtimex(&tx); | ||
121 | |||
122 | /* Clear the status */ | ||
123 | tx.modes = ADJ_STATUS; | ||
124 | tx.status = 0; | ||
125 | ret = adjtimex(&tx); | ||
126 | |||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | /* Make sure we cleanup on ctrl-c */ | ||
131 | void handler(int unused) | ||
132 | { | ||
133 | clear_time_state(); | ||
134 | exit(0); | ||
135 | } | ||
136 | |||
137 | /* Test for known hrtimer failure */ | ||
138 | void test_hrtimer_failure(void) | ||
139 | { | ||
140 | struct timespec now, target; | ||
141 | |||
142 | clock_gettime(CLOCK_REALTIME, &now); | ||
143 | target = timespec_add(now, NSEC_PER_SEC/2); | ||
144 | clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &target, NULL); | ||
145 | clock_gettime(CLOCK_REALTIME, &now); | ||
146 | |||
147 | if (!in_order(target, now)) | ||
148 | printf("ERROR: hrtimer early expiration failure observed.\n"); | ||
149 | } | ||
150 | |||
151 | int main(int argc, char **argv) | ||
152 | { | ||
153 | int settime = 0; | ||
154 | int tai_time = 0; | ||
155 | int insert = 1; | ||
156 | int iterations = -1; | ||
157 | int opt; | ||
158 | |||
159 | /* Process arguments */ | ||
160 | while ((opt = getopt(argc, argv, "sti:")) != -1) { | ||
161 | switch (opt) { | ||
162 | case 's': | ||
163 | printf("Setting time to speed up testing\n"); | ||
164 | settime = 1; | ||
165 | break; | ||
166 | case 'i': | ||
167 | iterations = atoi(optarg); | ||
168 | break; | ||
169 | case 't': | ||
170 | tai_time = 1; | ||
171 | break; | ||
172 | default: | ||
173 | printf("Usage: %s [-s] [-i <iterations>]\n", argv[0]); | ||
174 | printf(" -s: Set time to right before leap second each iteration\n"); | ||
175 | printf(" -i: Number of iterations\n"); | ||
176 | printf(" -t: Print TAI time\n"); | ||
177 | exit(-1); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* Make sure TAI support is present if -t was used */ | ||
182 | if (tai_time) { | ||
183 | struct timespec ts; | ||
184 | |||
185 | if (clock_gettime(CLOCK_TAI, &ts)) { | ||
186 | printf("System doesn't support CLOCK_TAI\n"); | ||
187 | ksft_exit_fail(); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | signal(SIGINT, handler); | ||
192 | signal(SIGKILL, handler); | ||
193 | |||
194 | if (iterations < 0) | ||
195 | printf("This runs continuously. Press ctrl-c to stop\n"); | ||
196 | else | ||
197 | printf("Running for %i iterations. Press ctrl-c to stop\n", iterations); | ||
198 | |||
199 | printf("\n"); | ||
200 | while (1) { | ||
201 | int ret; | ||
202 | struct timespec ts; | ||
203 | struct timex tx; | ||
204 | time_t now, next_leap; | ||
205 | |||
206 | /* Get the current time */ | ||
207 | clock_gettime(CLOCK_REALTIME, &ts); | ||
208 | |||
209 | /* Calculate the next possible leap second 23:59:60 GMT */ | ||
210 | next_leap = ts.tv_sec; | ||
211 | next_leap += 86400 - (next_leap % 86400); | ||
212 | |||
213 | if (settime) { | ||
214 | struct timeval tv; | ||
215 | |||
216 | tv.tv_sec = next_leap - 10; | ||
217 | tv.tv_usec = 0; | ||
218 | settimeofday(&tv, NULL); | ||
219 | printf("Setting time to %s", ctime(&tv.tv_sec)); | ||
220 | } | ||
221 | |||
222 | /* Reset NTP time state */ | ||
223 | clear_time_state(); | ||
224 | |||
225 | /* Set the leap second insert flag */ | ||
226 | tx.modes = ADJ_STATUS; | ||
227 | if (insert) | ||
228 | tx.status = STA_INS; | ||
229 | else | ||
230 | tx.status = STA_DEL; | ||
231 | ret = adjtimex(&tx); | ||
232 | if (ret < 0) { | ||
233 | printf("Error: Problem setting STA_INS/STA_DEL!: %s\n", | ||
234 | time_state_str(ret)); | ||
235 | return ksft_exit_fail(); | ||
236 | } | ||
237 | |||
238 | /* Validate STA_INS was set */ | ||
239 | tx.modes = 0; | ||
240 | ret = adjtimex(&tx); | ||
241 | if (tx.status != STA_INS && tx.status != STA_DEL) { | ||
242 | printf("Error: STA_INS/STA_DEL not set!: %s\n", | ||
243 | time_state_str(ret)); | ||
244 | return ksft_exit_fail(); | ||
245 | } | ||
246 | |||
247 | if (tai_time) { | ||
248 | printf("Using TAI time," | ||
249 | " no inconsistencies should be seen!\n"); | ||
250 | } | ||
251 | |||
252 | printf("Scheduling leap second for %s", ctime(&next_leap)); | ||
253 | |||
254 | /* Wake up 3 seconds before leap */ | ||
255 | ts.tv_sec = next_leap - 3; | ||
256 | ts.tv_nsec = 0; | ||
257 | |||
258 | while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL)) | ||
259 | printf("Something woke us up, returning to sleep\n"); | ||
260 | |||
261 | /* Validate STA_INS is still set */ | ||
262 | tx.modes = 0; | ||
263 | ret = adjtimex(&tx); | ||
264 | if (tx.status != STA_INS && tx.status != STA_DEL) { | ||
265 | printf("Something cleared STA_INS/STA_DEL, setting it again.\n"); | ||
266 | tx.modes = ADJ_STATUS; | ||
267 | if (insert) | ||
268 | tx.status = STA_INS; | ||
269 | else | ||
270 | tx.status = STA_DEL; | ||
271 | ret = adjtimex(&tx); | ||
272 | } | ||
273 | |||
274 | /* Check adjtimex output every half second */ | ||
275 | now = tx.time.tv_sec; | ||
276 | while (now < next_leap + 2) { | ||
277 | char buf[26]; | ||
278 | struct timespec tai; | ||
279 | |||
280 | tx.modes = 0; | ||
281 | ret = adjtimex(&tx); | ||
282 | |||
283 | if (tai_time) { | ||
284 | clock_gettime(CLOCK_TAI, &tai); | ||
285 | printf("%ld sec, %9ld ns\t%s\n", | ||
286 | tai.tv_sec, | ||
287 | tai.tv_nsec, | ||
288 | time_state_str(ret)); | ||
289 | } else { | ||
290 | ctime_r(&tx.time.tv_sec, buf); | ||
291 | buf[strlen(buf)-1] = 0; /*remove trailing\n */ | ||
292 | |||
293 | printf("%s + %6ld us (%i)\t%s\n", | ||
294 | buf, | ||
295 | tx.time.tv_usec, | ||
296 | tx.tai, | ||
297 | time_state_str(ret)); | ||
298 | } | ||
299 | now = tx.time.tv_sec; | ||
300 | /* Sleep for another half second */ | ||
301 | ts.tv_sec = 0; | ||
302 | ts.tv_nsec = NSEC_PER_SEC / 2; | ||
303 | clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); | ||
304 | } | ||
305 | /* Switch to using other mode */ | ||
306 | insert = !insert; | ||
307 | |||
308 | /* Note if kernel has known hrtimer failure */ | ||
309 | test_hrtimer_failure(); | ||
310 | |||
311 | printf("Leap complete\n\n"); | ||
312 | |||
313 | if ((iterations != -1) && !(--iterations)) | ||
314 | break; | ||
315 | } | ||
316 | |||
317 | clear_time_state(); | ||
318 | return ksft_exit_pass(); | ||
319 | } | ||
diff --git a/tools/testing/selftests/timers/leapcrash.c b/tools/testing/selftests/timers/leapcrash.c new file mode 100644 index 000000000000..a1071bdbdeb7 --- /dev/null +++ b/tools/testing/selftests/timers/leapcrash.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* Demo leapsecond deadlock | ||
2 | * by: John Stultz (john.stultz@linaro.org) | ||
3 | * (C) Copyright IBM 2012 | ||
4 | * (C) Copyright 2013, 2015 Linaro Limited | ||
5 | * Licensed under the GPL | ||
6 | * | ||
7 | * This test demonstrates leapsecond deadlock that is possibe | ||
8 | * on kernels from 2.6.26 to 3.3. | ||
9 | * | ||
10 | * WARNING: THIS WILL LIKELY HARDHANG SYSTEMS AND MAY LOSE DATA | ||
11 | * RUN AT YOUR OWN RISK! | ||
12 | * To build: | ||
13 | * $ gcc leapcrash.c -o leapcrash -lrt | ||
14 | */ | ||
15 | |||
16 | |||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <time.h> | ||
21 | #include <sys/time.h> | ||
22 | #include <sys/timex.h> | ||
23 | #include <string.h> | ||
24 | #include <signal.h> | ||
25 | #ifdef KTEST | ||
26 | #include "../kselftest.h" | ||
27 | #else | ||
28 | static inline int ksft_exit_pass(void) | ||
29 | { | ||
30 | exit(0); | ||
31 | } | ||
32 | static inline int ksft_exit_fail(void) | ||
33 | { | ||
34 | exit(1); | ||
35 | } | ||
36 | #endif | ||
37 | |||
38 | |||
39 | |||
40 | /* clear NTP time_status & time_state */ | ||
41 | int clear_time_state(void) | ||
42 | { | ||
43 | struct timex tx; | ||
44 | int ret; | ||
45 | |||
46 | /* | ||
47 | * We have to call adjtime twice here, as kernels | ||
48 | * prior to 6b1859dba01c7 (included in 3.5 and | ||
49 | * -stable), had an issue with the state machine | ||
50 | * and wouldn't clear the STA_INS/DEL flag directly. | ||
51 | */ | ||
52 | tx.modes = ADJ_STATUS; | ||
53 | tx.status = STA_PLL; | ||
54 | ret = adjtimex(&tx); | ||
55 | |||
56 | tx.modes = ADJ_STATUS; | ||
57 | tx.status = 0; | ||
58 | ret = adjtimex(&tx); | ||
59 | |||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | /* Make sure we cleanup on ctrl-c */ | ||
64 | void handler(int unused) | ||
65 | { | ||
66 | clear_time_state(); | ||
67 | exit(0); | ||
68 | } | ||
69 | |||
70 | |||
71 | int main(void) | ||
72 | { | ||
73 | struct timex tx; | ||
74 | struct timespec ts; | ||
75 | time_t next_leap; | ||
76 | int count = 0; | ||
77 | |||
78 | setbuf(stdout, NULL); | ||
79 | |||
80 | signal(SIGINT, handler); | ||
81 | signal(SIGKILL, handler); | ||
82 | printf("This runs for a few minutes. Press ctrl-c to stop\n"); | ||
83 | |||
84 | clear_time_state(); | ||
85 | |||
86 | |||
87 | /* Get the current time */ | ||
88 | clock_gettime(CLOCK_REALTIME, &ts); | ||
89 | |||
90 | /* Calculate the next possible leap second 23:59:60 GMT */ | ||
91 | next_leap = ts.tv_sec; | ||
92 | next_leap += 86400 - (next_leap % 86400); | ||
93 | |||
94 | for (count = 0; count < 20; count++) { | ||
95 | struct timeval tv; | ||
96 | |||
97 | |||
98 | /* set the time to 2 seconds before the leap */ | ||
99 | tv.tv_sec = next_leap - 2; | ||
100 | tv.tv_usec = 0; | ||
101 | if (settimeofday(&tv, NULL)) { | ||
102 | printf("Error: You're likely not running with proper (ie: root) permissions\n"); | ||
103 | return ksft_exit_fail(); | ||
104 | } | ||
105 | tx.modes = 0; | ||
106 | adjtimex(&tx); | ||
107 | |||
108 | /* hammer on adjtime w/ STA_INS */ | ||
109 | while (tx.time.tv_sec < next_leap + 1) { | ||
110 | /* Set the leap second insert flag */ | ||
111 | tx.modes = ADJ_STATUS; | ||
112 | tx.status = STA_INS; | ||
113 | adjtimex(&tx); | ||
114 | } | ||
115 | clear_time_state(); | ||
116 | printf("."); | ||
117 | } | ||
118 | printf("[OK]\n"); | ||
119 | return ksft_exit_pass(); | ||
120 | } | ||
diff --git a/tools/testing/selftests/timers/mqueue-lat.c b/tools/testing/selftests/timers/mqueue-lat.c new file mode 100644 index 000000000000..a2a3924d0b41 --- /dev/null +++ b/tools/testing/selftests/timers/mqueue-lat.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* Measure mqueue timeout latency | ||
2 | * by: john stultz (john.stultz@linaro.org) | ||
3 | * (C) Copyright Linaro 2013 | ||
4 | * | ||
5 | * Inspired with permission from example test by: | ||
6 | * Romain Francoise <romain@orebokech.com> | ||
7 | * Licensed under the GPLv2 | ||
8 | * | ||
9 | * To build: | ||
10 | * $ gcc mqueue-lat.c -o mqueue-lat -lrt | ||
11 | * | ||
12 | * This program is free software: you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation, either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <time.h> | ||
26 | #include <sys/time.h> | ||
27 | #include <sys/timex.h> | ||
28 | #include <string.h> | ||
29 | #include <signal.h> | ||
30 | #include <errno.h> | ||
31 | #include <mqueue.h> | ||
32 | #ifdef KTEST | ||
33 | #include "../kselftest.h" | ||
34 | #else | ||
35 | static inline int ksft_exit_pass(void) | ||
36 | { | ||
37 | exit(0); | ||
38 | } | ||
39 | static inline int ksft_exit_fail(void) | ||
40 | { | ||
41 | exit(1); | ||
42 | } | ||
43 | #endif | ||
44 | |||
45 | #define NSEC_PER_SEC 1000000000ULL | ||
46 | |||
47 | #define TARGET_TIMEOUT 100000000 /* 100ms in nanoseconds */ | ||
48 | #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ | ||
49 | |||
50 | |||
51 | long long timespec_sub(struct timespec a, struct timespec b) | ||
52 | { | ||
53 | long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; | ||
54 | |||
55 | ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | struct timespec timespec_add(struct timespec ts, unsigned long long ns) | ||
60 | { | ||
61 | ts.tv_nsec += ns; | ||
62 | while (ts.tv_nsec >= NSEC_PER_SEC) { | ||
63 | ts.tv_nsec -= NSEC_PER_SEC; | ||
64 | ts.tv_sec++; | ||
65 | } | ||
66 | return ts; | ||
67 | } | ||
68 | |||
69 | int mqueue_lat_test(void) | ||
70 | { | ||
71 | |||
72 | mqd_t q; | ||
73 | struct mq_attr attr; | ||
74 | struct timespec start, end, now, target; | ||
75 | int i, count, ret; | ||
76 | |||
77 | q = mq_open("/foo", O_CREAT | O_RDONLY, 0666, NULL); | ||
78 | if (q < 0) { | ||
79 | perror("mq_open"); | ||
80 | return -1; | ||
81 | } | ||
82 | mq_getattr(q, &attr); | ||
83 | |||
84 | |||
85 | count = 100; | ||
86 | clock_gettime(CLOCK_MONOTONIC, &start); | ||
87 | |||
88 | for (i = 0; i < count; i++) { | ||
89 | char buf[attr.mq_msgsize]; | ||
90 | |||
91 | clock_gettime(CLOCK_REALTIME, &now); | ||
92 | target = now; | ||
93 | target = timespec_add(now, TARGET_TIMEOUT); /* 100ms */ | ||
94 | |||
95 | ret = mq_timedreceive(q, buf, sizeof(buf), NULL, &target); | ||
96 | if (ret < 0 && errno != ETIMEDOUT) { | ||
97 | perror("mq_timedreceive"); | ||
98 | return -1; | ||
99 | } | ||
100 | } | ||
101 | clock_gettime(CLOCK_MONOTONIC, &end); | ||
102 | |||
103 | mq_close(q); | ||
104 | |||
105 | if ((timespec_sub(start, end)/count) > TARGET_TIMEOUT + UNRESONABLE_LATENCY) | ||
106 | return -1; | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | int main(int argc, char **argv) | ||
112 | { | ||
113 | int ret; | ||
114 | |||
115 | printf("Mqueue latency : "); | ||
116 | |||
117 | ret = mqueue_lat_test(); | ||
118 | if (ret < 0) { | ||
119 | printf("[FAILED]\n"); | ||
120 | return ksft_exit_fail(); | ||
121 | } | ||
122 | printf("[OK]\n"); | ||
123 | return ksft_exit_pass(); | ||
124 | } | ||
diff --git a/tools/testing/selftests/timers/nanosleep.c b/tools/testing/selftests/timers/nanosleep.c new file mode 100644 index 000000000000..8a3c29de7d49 --- /dev/null +++ b/tools/testing/selftests/timers/nanosleep.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /* Make sure timers don't return early | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * John Stultz (john.stultz@linaro.org) | ||
4 | * (C) Copyright IBM 2012 | ||
5 | * (C) Copyright Linaro 2013 2015 | ||
6 | * Licensed under the GPLv2 | ||
7 | * | ||
8 | * To build: | ||
9 | * $ gcc nanosleep.c -o nanosleep -lrt | ||
10 | * | ||
11 | * This program is free software: you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | */ | ||
21 | |||
22 | #include <stdio.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <time.h> | ||
25 | #include <sys/time.h> | ||
26 | #include <sys/timex.h> | ||
27 | #include <string.h> | ||
28 | #include <signal.h> | ||
29 | #ifdef KTEST | ||
30 | #include "../kselftest.h" | ||
31 | #else | ||
32 | static inline int ksft_exit_pass(void) | ||
33 | { | ||
34 | exit(0); | ||
35 | } | ||
36 | static inline int ksft_exit_fail(void) | ||
37 | { | ||
38 | exit(1); | ||
39 | } | ||
40 | #endif | ||
41 | |||
42 | #define NSEC_PER_SEC 1000000000ULL | ||
43 | |||
44 | #define CLOCK_REALTIME 0 | ||
45 | #define CLOCK_MONOTONIC 1 | ||
46 | #define CLOCK_PROCESS_CPUTIME_ID 2 | ||
47 | #define CLOCK_THREAD_CPUTIME_ID 3 | ||
48 | #define CLOCK_MONOTONIC_RAW 4 | ||
49 | #define CLOCK_REALTIME_COARSE 5 | ||
50 | #define CLOCK_MONOTONIC_COARSE 6 | ||
51 | #define CLOCK_BOOTTIME 7 | ||
52 | #define CLOCK_REALTIME_ALARM 8 | ||
53 | #define CLOCK_BOOTTIME_ALARM 9 | ||
54 | #define CLOCK_HWSPECIFIC 10 | ||
55 | #define CLOCK_TAI 11 | ||
56 | #define NR_CLOCKIDS 12 | ||
57 | |||
58 | #define UNSUPPORTED 0xf00f | ||
59 | |||
60 | char *clockstring(int clockid) | ||
61 | { | ||
62 | switch (clockid) { | ||
63 | case CLOCK_REALTIME: | ||
64 | return "CLOCK_REALTIME"; | ||
65 | case CLOCK_MONOTONIC: | ||
66 | return "CLOCK_MONOTONIC"; | ||
67 | case CLOCK_PROCESS_CPUTIME_ID: | ||
68 | return "CLOCK_PROCESS_CPUTIME_ID"; | ||
69 | case CLOCK_THREAD_CPUTIME_ID: | ||
70 | return "CLOCK_THREAD_CPUTIME_ID"; | ||
71 | case CLOCK_MONOTONIC_RAW: | ||
72 | return "CLOCK_MONOTONIC_RAW"; | ||
73 | case CLOCK_REALTIME_COARSE: | ||
74 | return "CLOCK_REALTIME_COARSE"; | ||
75 | case CLOCK_MONOTONIC_COARSE: | ||
76 | return "CLOCK_MONOTONIC_COARSE"; | ||
77 | case CLOCK_BOOTTIME: | ||
78 | return "CLOCK_BOOTTIME"; | ||
79 | case CLOCK_REALTIME_ALARM: | ||
80 | return "CLOCK_REALTIME_ALARM"; | ||
81 | case CLOCK_BOOTTIME_ALARM: | ||
82 | return "CLOCK_BOOTTIME_ALARM"; | ||
83 | case CLOCK_TAI: | ||
84 | return "CLOCK_TAI"; | ||
85 | }; | ||
86 | return "UNKNOWN_CLOCKID"; | ||
87 | } | ||
88 | |||
89 | /* returns 1 if a <= b, 0 otherwise */ | ||
90 | static inline int in_order(struct timespec a, struct timespec b) | ||
91 | { | ||
92 | if (a.tv_sec < b.tv_sec) | ||
93 | return 1; | ||
94 | if (a.tv_sec > b.tv_sec) | ||
95 | return 0; | ||
96 | if (a.tv_nsec > b.tv_nsec) | ||
97 | return 0; | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | struct timespec timespec_add(struct timespec ts, unsigned long long ns) | ||
102 | { | ||
103 | ts.tv_nsec += ns; | ||
104 | while (ts.tv_nsec >= NSEC_PER_SEC) { | ||
105 | ts.tv_nsec -= NSEC_PER_SEC; | ||
106 | ts.tv_sec++; | ||
107 | } | ||
108 | return ts; | ||
109 | } | ||
110 | |||
111 | int nanosleep_test(int clockid, long long ns) | ||
112 | { | ||
113 | struct timespec now, target, rel; | ||
114 | |||
115 | /* First check abs time */ | ||
116 | if (clock_gettime(clockid, &now)) | ||
117 | return UNSUPPORTED; | ||
118 | target = timespec_add(now, ns); | ||
119 | |||
120 | if (clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL)) | ||
121 | return UNSUPPORTED; | ||
122 | clock_gettime(clockid, &now); | ||
123 | |||
124 | if (!in_order(target, now)) | ||
125 | return -1; | ||
126 | |||
127 | /* Second check reltime */ | ||
128 | clock_gettime(clockid, &now); | ||
129 | rel.tv_sec = 0; | ||
130 | rel.tv_nsec = 0; | ||
131 | rel = timespec_add(rel, ns); | ||
132 | target = timespec_add(now, ns); | ||
133 | clock_nanosleep(clockid, 0, &rel, NULL); | ||
134 | clock_gettime(clockid, &now); | ||
135 | |||
136 | if (!in_order(target, now)) | ||
137 | return -1; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | int main(int argc, char **argv) | ||
142 | { | ||
143 | long long length; | ||
144 | int clockid, ret; | ||
145 | |||
146 | for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) { | ||
147 | |||
148 | /* Skip cputime clockids since nanosleep won't increment cputime */ | ||
149 | if (clockid == CLOCK_PROCESS_CPUTIME_ID || | ||
150 | clockid == CLOCK_THREAD_CPUTIME_ID || | ||
151 | clockid == CLOCK_HWSPECIFIC) | ||
152 | continue; | ||
153 | |||
154 | printf("Nanosleep %-31s ", clockstring(clockid)); | ||
155 | |||
156 | length = 10; | ||
157 | while (length <= (NSEC_PER_SEC * 10)) { | ||
158 | ret = nanosleep_test(clockid, length); | ||
159 | if (ret == UNSUPPORTED) { | ||
160 | printf("[UNSUPPORTED]\n"); | ||
161 | goto next; | ||
162 | } | ||
163 | if (ret < 0) { | ||
164 | printf("[FAILED]\n"); | ||
165 | return ksft_exit_fail(); | ||
166 | } | ||
167 | length *= 100; | ||
168 | } | ||
169 | printf("[OK]\n"); | ||
170 | next: | ||
171 | ret = 0; | ||
172 | } | ||
173 | return ksft_exit_pass(); | ||
174 | } | ||
diff --git a/tools/testing/selftests/timers/nsleep-lat.c b/tools/testing/selftests/timers/nsleep-lat.c new file mode 100644 index 000000000000..2d7898fda0f1 --- /dev/null +++ b/tools/testing/selftests/timers/nsleep-lat.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* Measure nanosleep timer latency | ||
2 | * by: john stultz (john.stultz@linaro.org) | ||
3 | * (C) Copyright Linaro 2013 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * To build: | ||
7 | * $ gcc nsleep-lat.c -o nsleep-lat -lrt | ||
8 | * | ||
9 | * This program is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <time.h> | ||
23 | #include <sys/time.h> | ||
24 | #include <sys/timex.h> | ||
25 | #include <string.h> | ||
26 | #include <signal.h> | ||
27 | #ifdef KTEST | ||
28 | #include "../kselftest.h" | ||
29 | #else | ||
30 | static inline int ksft_exit_pass(void) | ||
31 | { | ||
32 | exit(0); | ||
33 | } | ||
34 | static inline int ksft_exit_fail(void) | ||
35 | { | ||
36 | exit(1); | ||
37 | } | ||
38 | #endif | ||
39 | |||
40 | #define NSEC_PER_SEC 1000000000ULL | ||
41 | |||
42 | #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ | ||
43 | |||
44 | |||
45 | #define CLOCK_REALTIME 0 | ||
46 | #define CLOCK_MONOTONIC 1 | ||
47 | #define CLOCK_PROCESS_CPUTIME_ID 2 | ||
48 | #define CLOCK_THREAD_CPUTIME_ID 3 | ||
49 | #define CLOCK_MONOTONIC_RAW 4 | ||
50 | #define CLOCK_REALTIME_COARSE 5 | ||
51 | #define CLOCK_MONOTONIC_COARSE 6 | ||
52 | #define CLOCK_BOOTTIME 7 | ||
53 | #define CLOCK_REALTIME_ALARM 8 | ||
54 | #define CLOCK_BOOTTIME_ALARM 9 | ||
55 | #define CLOCK_HWSPECIFIC 10 | ||
56 | #define CLOCK_TAI 11 | ||
57 | #define NR_CLOCKIDS 12 | ||
58 | |||
59 | #define UNSUPPORTED 0xf00f | ||
60 | |||
61 | char *clockstring(int clockid) | ||
62 | { | ||
63 | switch (clockid) { | ||
64 | case CLOCK_REALTIME: | ||
65 | return "CLOCK_REALTIME"; | ||
66 | case CLOCK_MONOTONIC: | ||
67 | return "CLOCK_MONOTONIC"; | ||
68 | case CLOCK_PROCESS_CPUTIME_ID: | ||
69 | return "CLOCK_PROCESS_CPUTIME_ID"; | ||
70 | case CLOCK_THREAD_CPUTIME_ID: | ||
71 | return "CLOCK_THREAD_CPUTIME_ID"; | ||
72 | case CLOCK_MONOTONIC_RAW: | ||
73 | return "CLOCK_MONOTONIC_RAW"; | ||
74 | case CLOCK_REALTIME_COARSE: | ||
75 | return "CLOCK_REALTIME_COARSE"; | ||
76 | case CLOCK_MONOTONIC_COARSE: | ||
77 | return "CLOCK_MONOTONIC_COARSE"; | ||
78 | case CLOCK_BOOTTIME: | ||
79 | return "CLOCK_BOOTTIME"; | ||
80 | case CLOCK_REALTIME_ALARM: | ||
81 | return "CLOCK_REALTIME_ALARM"; | ||
82 | case CLOCK_BOOTTIME_ALARM: | ||
83 | return "CLOCK_BOOTTIME_ALARM"; | ||
84 | case CLOCK_TAI: | ||
85 | return "CLOCK_TAI"; | ||
86 | }; | ||
87 | return "UNKNOWN_CLOCKID"; | ||
88 | } | ||
89 | |||
90 | struct timespec timespec_add(struct timespec ts, unsigned long long ns) | ||
91 | { | ||
92 | ts.tv_nsec += ns; | ||
93 | while (ts.tv_nsec >= NSEC_PER_SEC) { | ||
94 | ts.tv_nsec -= NSEC_PER_SEC; | ||
95 | ts.tv_sec++; | ||
96 | } | ||
97 | return ts; | ||
98 | } | ||
99 | |||
100 | |||
101 | long long timespec_sub(struct timespec a, struct timespec b) | ||
102 | { | ||
103 | long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; | ||
104 | |||
105 | ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | int nanosleep_lat_test(int clockid, long long ns) | ||
110 | { | ||
111 | struct timespec start, end, target; | ||
112 | long long latency = 0; | ||
113 | int i, count; | ||
114 | |||
115 | target.tv_sec = ns/NSEC_PER_SEC; | ||
116 | target.tv_nsec = ns%NSEC_PER_SEC; | ||
117 | |||
118 | if (clock_gettime(clockid, &start)) | ||
119 | return UNSUPPORTED; | ||
120 | if (clock_nanosleep(clockid, 0, &target, NULL)) | ||
121 | return UNSUPPORTED; | ||
122 | |||
123 | count = 10; | ||
124 | |||
125 | /* First check relative latency */ | ||
126 | clock_gettime(clockid, &start); | ||
127 | for (i = 0; i < count; i++) | ||
128 | clock_nanosleep(clockid, 0, &target, NULL); | ||
129 | clock_gettime(clockid, &end); | ||
130 | |||
131 | if (((timespec_sub(start, end)/count)-ns) > UNRESONABLE_LATENCY) { | ||
132 | printf("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns); | ||
133 | return -1; | ||
134 | } | ||
135 | |||
136 | /* Next check absolute latency */ | ||
137 | for (i = 0; i < count; i++) { | ||
138 | clock_gettime(clockid, &start); | ||
139 | target = timespec_add(start, ns); | ||
140 | clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL); | ||
141 | clock_gettime(clockid, &end); | ||
142 | latency += timespec_sub(target, end); | ||
143 | } | ||
144 | |||
145 | if (latency/count > UNRESONABLE_LATENCY) { | ||
146 | printf("Large abs latency: %lld ns :", latency/count); | ||
147 | return -1; | ||
148 | } | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | |||
154 | |||
155 | int main(int argc, char **argv) | ||
156 | { | ||
157 | long long length; | ||
158 | int clockid, ret; | ||
159 | |||
160 | for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) { | ||
161 | |||
162 | /* Skip cputime clockids since nanosleep won't increment cputime */ | ||
163 | if (clockid == CLOCK_PROCESS_CPUTIME_ID || | ||
164 | clockid == CLOCK_THREAD_CPUTIME_ID || | ||
165 | clockid == CLOCK_HWSPECIFIC) | ||
166 | continue; | ||
167 | |||
168 | printf("nsleep latency %-26s ", clockstring(clockid)); | ||
169 | |||
170 | length = 10; | ||
171 | while (length <= (NSEC_PER_SEC * 10)) { | ||
172 | ret = nanosleep_lat_test(clockid, length); | ||
173 | if (ret) | ||
174 | break; | ||
175 | length *= 100; | ||
176 | |||
177 | } | ||
178 | |||
179 | if (ret == UNSUPPORTED) { | ||
180 | printf("[UNSUPPORTED]\n"); | ||
181 | continue; | ||
182 | } | ||
183 | if (ret < 0) { | ||
184 | printf("[FAILED]\n"); | ||
185 | return ksft_exit_fail(); | ||
186 | } | ||
187 | printf("[OK]\n"); | ||
188 | } | ||
189 | return ksft_exit_pass(); | ||
190 | } | ||
diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index f87d970a485c..5a246a02dff3 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c | |||
@@ -35,10 +35,11 @@ static void user_loop(void) | |||
35 | static void kernel_loop(void) | 35 | static void kernel_loop(void) |
36 | { | 36 | { |
37 | void *addr = sbrk(0); | 37 | void *addr = sbrk(0); |
38 | int err = 0; | ||
38 | 39 | ||
39 | while (!done) { | 40 | while (!done && !err) { |
40 | brk(addr + 4096); | 41 | err = brk(addr + 4096); |
41 | brk(addr); | 42 | err |= brk(addr); |
42 | } | 43 | } |
43 | } | 44 | } |
44 | 45 | ||
@@ -190,8 +191,6 @@ static int check_timer_create(int which) | |||
190 | 191 | ||
191 | int main(int argc, char **argv) | 192 | int main(int argc, char **argv) |
192 | { | 193 | { |
193 | int err; | ||
194 | |||
195 | printf("Testing posix timers. False negative may happen on CPU execution \n"); | 194 | printf("Testing posix timers. False negative may happen on CPU execution \n"); |
196 | printf("based timers if other threads run on the CPU...\n"); | 195 | printf("based timers if other threads run on the CPU...\n"); |
197 | 196 | ||
diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c new file mode 100644 index 000000000000..30906bfd9c1b --- /dev/null +++ b/tools/testing/selftests/timers/raw_skew.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* CLOCK_MONOTONIC vs CLOCK_MONOTONIC_RAW skew test | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * John Stultz <john.stultz@linaro.org> | ||
4 | * (C) Copyright IBM 2012 | ||
5 | * (C) Copyright Linaro Limited 2015 | ||
6 | * Licensed under the GPLv2 | ||
7 | * | ||
8 | * To build: | ||
9 | * $ gcc raw_skew.c -o raw_skew -lrt | ||
10 | * | ||
11 | * This program is free software: you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | */ | ||
21 | |||
22 | #include <stdio.h> | ||
23 | #include <unistd.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <sys/time.h> | ||
26 | #include <sys/timex.h> | ||
27 | #include <time.h> | ||
28 | #ifdef KTEST | ||
29 | #include "../kselftest.h" | ||
30 | #else | ||
31 | static inline int ksft_exit_pass(void) | ||
32 | { | ||
33 | exit(0); | ||
34 | } | ||
35 | static inline int ksft_exit_fail(void) | ||
36 | { | ||
37 | exit(1); | ||
38 | } | ||
39 | #endif | ||
40 | |||
41 | |||
42 | #define CLOCK_MONOTONIC_RAW 4 | ||
43 | #define NSEC_PER_SEC 1000000000LL | ||
44 | |||
45 | #define shift_right(x, s) ({ \ | ||
46 | __typeof__(x) __x = (x); \ | ||
47 | __typeof__(s) __s = (s); \ | ||
48 | __x < 0 ? -(-__x >> __s) : __x >> __s; \ | ||
49 | }) | ||
50 | |||
51 | long long llabs(long long val) | ||
52 | { | ||
53 | if (val < 0) | ||
54 | val = -val; | ||
55 | return val; | ||
56 | } | ||
57 | |||
58 | unsigned long long ts_to_nsec(struct timespec ts) | ||
59 | { | ||
60 | return ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; | ||
61 | } | ||
62 | |||
63 | struct timespec nsec_to_ts(long long ns) | ||
64 | { | ||
65 | struct timespec ts; | ||
66 | |||
67 | ts.tv_sec = ns/NSEC_PER_SEC; | ||
68 | ts.tv_nsec = ns%NSEC_PER_SEC; | ||
69 | return ts; | ||
70 | } | ||
71 | |||
72 | long long diff_timespec(struct timespec start, struct timespec end) | ||
73 | { | ||
74 | long long start_ns, end_ns; | ||
75 | |||
76 | start_ns = ts_to_nsec(start); | ||
77 | end_ns = ts_to_nsec(end); | ||
78 | return end_ns - start_ns; | ||
79 | } | ||
80 | |||
81 | void get_monotonic_and_raw(struct timespec *mon, struct timespec *raw) | ||
82 | { | ||
83 | struct timespec start, mid, end; | ||
84 | long long diff = 0, tmp; | ||
85 | int i; | ||
86 | |||
87 | for (i = 0; i < 3; i++) { | ||
88 | long long newdiff; | ||
89 | |||
90 | clock_gettime(CLOCK_MONOTONIC, &start); | ||
91 | clock_gettime(CLOCK_MONOTONIC_RAW, &mid); | ||
92 | clock_gettime(CLOCK_MONOTONIC, &end); | ||
93 | |||
94 | newdiff = diff_timespec(start, end); | ||
95 | if (diff == 0 || newdiff < diff) { | ||
96 | diff = newdiff; | ||
97 | *raw = mid; | ||
98 | tmp = (ts_to_nsec(start) + ts_to_nsec(end))/2; | ||
99 | *mon = nsec_to_ts(tmp); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | int main(int argv, char **argc) | ||
105 | { | ||
106 | struct timespec mon, raw, start, end; | ||
107 | long long delta1, delta2, interval, eppm, ppm; | ||
108 | struct timex tx1, tx2; | ||
109 | |||
110 | setbuf(stdout, NULL); | ||
111 | |||
112 | if (clock_gettime(CLOCK_MONOTONIC_RAW, &raw)) { | ||
113 | printf("ERR: NO CLOCK_MONOTONIC_RAW\n"); | ||
114 | return -1; | ||
115 | } | ||
116 | |||
117 | tx1.modes = 0; | ||
118 | adjtimex(&tx1); | ||
119 | get_monotonic_and_raw(&mon, &raw); | ||
120 | start = mon; | ||
121 | delta1 = diff_timespec(mon, raw); | ||
122 | |||
123 | if (tx1.offset) | ||
124 | printf("WARNING: ADJ_OFFSET in progress, this will cause inaccurate results\n"); | ||
125 | |||
126 | printf("Estimating clock drift: "); | ||
127 | sleep(120); | ||
128 | |||
129 | get_monotonic_and_raw(&mon, &raw); | ||
130 | end = mon; | ||
131 | tx2.modes = 0; | ||
132 | adjtimex(&tx2); | ||
133 | delta2 = diff_timespec(mon, raw); | ||
134 | |||
135 | interval = diff_timespec(start, end); | ||
136 | |||
137 | /* calculate measured ppm between MONOTONIC and MONOTONIC_RAW */ | ||
138 | eppm = ((delta2-delta1)*NSEC_PER_SEC)/interval; | ||
139 | eppm = -eppm; | ||
140 | printf("%lld.%i(est)", eppm/1000, abs((int)(eppm%1000))); | ||
141 | |||
142 | /* Avg the two actual freq samples adjtimex gave us */ | ||
143 | ppm = (tx1.freq + tx2.freq) * 1000 / 2; | ||
144 | ppm = (long long)tx1.freq * 1000; | ||
145 | ppm = shift_right(ppm, 16); | ||
146 | printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000))); | ||
147 | |||
148 | if (llabs(eppm - ppm) > 1000) { | ||
149 | printf(" [FAILED]\n"); | ||
150 | return ksft_exit_fail(); | ||
151 | } | ||
152 | printf(" [OK]\n"); | ||
153 | return ksft_exit_pass(); | ||
154 | } | ||
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c new file mode 100644 index 000000000000..d80ae852334d --- /dev/null +++ b/tools/testing/selftests/timers/rtctest.c | |||
@@ -0,0 +1,271 @@ | |||
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 | |||
25 | /* | ||
26 | * This expects the new RTC class driver framework, working with | ||
27 | * clocks that will often not be clones of what the PC-AT had. | ||
28 | * Use the command line to specify another RTC if you need one. | ||
29 | */ | ||
30 | static const char default_rtc[] = "/dev/rtc0"; | ||
31 | |||
32 | |||
33 | int main(int argc, char **argv) | ||
34 | { | ||
35 | int i, fd, retval, irqcount = 0; | ||
36 | unsigned long tmp, data; | ||
37 | struct rtc_time rtc_tm; | ||
38 | const char *rtc = default_rtc; | ||
39 | struct timeval start, end, diff; | ||
40 | |||
41 | switch (argc) { | ||
42 | case 2: | ||
43 | rtc = argv[1]; | ||
44 | /* FALLTHROUGH */ | ||
45 | case 1: | ||
46 | break; | ||
47 | default: | ||
48 | fprintf(stderr, "usage: rtctest [rtcdev]\n"); | ||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | fd = open(rtc, O_RDONLY); | ||
53 | |||
54 | if (fd == -1) { | ||
55 | perror(rtc); | ||
56 | exit(errno); | ||
57 | } | ||
58 | |||
59 | fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); | ||
60 | |||
61 | /* Turn on update interrupts (one per second) */ | ||
62 | retval = ioctl(fd, RTC_UIE_ON, 0); | ||
63 | if (retval == -1) { | ||
64 | if (errno == ENOTTY) { | ||
65 | fprintf(stderr, | ||
66 | "\n...Update IRQs not supported.\n"); | ||
67 | goto test_READ; | ||
68 | } | ||
69 | perror("RTC_UIE_ON ioctl"); | ||
70 | exit(errno); | ||
71 | } | ||
72 | |||
73 | fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", | ||
74 | rtc); | ||
75 | fflush(stderr); | ||
76 | for (i=1; i<6; i++) { | ||
77 | /* This read will block */ | ||
78 | retval = read(fd, &data, sizeof(unsigned long)); | ||
79 | if (retval == -1) { | ||
80 | perror("read"); | ||
81 | exit(errno); | ||
82 | } | ||
83 | fprintf(stderr, " %d",i); | ||
84 | fflush(stderr); | ||
85 | irqcount++; | ||
86 | } | ||
87 | |||
88 | fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); | ||
89 | fflush(stderr); | ||
90 | for (i=1; i<6; i++) { | ||
91 | struct timeval tv = {5, 0}; /* 5 second timeout on select */ | ||
92 | fd_set readfds; | ||
93 | |||
94 | FD_ZERO(&readfds); | ||
95 | FD_SET(fd, &readfds); | ||
96 | /* The select will wait until an RTC interrupt happens. */ | ||
97 | retval = select(fd+1, &readfds, NULL, NULL, &tv); | ||
98 | if (retval == -1) { | ||
99 | perror("select"); | ||
100 | exit(errno); | ||
101 | } | ||
102 | /* This read won't block unlike the select-less case above. */ | ||
103 | retval = read(fd, &data, sizeof(unsigned long)); | ||
104 | if (retval == -1) { | ||
105 | perror("read"); | ||
106 | exit(errno); | ||
107 | } | ||
108 | fprintf(stderr, " %d",i); | ||
109 | fflush(stderr); | ||
110 | irqcount++; | ||
111 | } | ||
112 | |||
113 | /* Turn off update interrupts */ | ||
114 | retval = ioctl(fd, RTC_UIE_OFF, 0); | ||
115 | if (retval == -1) { | ||
116 | perror("RTC_UIE_OFF ioctl"); | ||
117 | exit(errno); | ||
118 | } | ||
119 | |||
120 | test_READ: | ||
121 | /* Read the RTC time/date */ | ||
122 | retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); | ||
123 | if (retval == -1) { | ||
124 | perror("RTC_RD_TIME ioctl"); | ||
125 | exit(errno); | ||
126 | } | ||
127 | |||
128 | fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", | ||
129 | rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, | ||
130 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); | ||
131 | |||
132 | /* Set the alarm to 5 sec in the future, and check for rollover */ | ||
133 | rtc_tm.tm_sec += 5; | ||
134 | if (rtc_tm.tm_sec >= 60) { | ||
135 | rtc_tm.tm_sec %= 60; | ||
136 | rtc_tm.tm_min++; | ||
137 | } | ||
138 | if (rtc_tm.tm_min == 60) { | ||
139 | rtc_tm.tm_min = 0; | ||
140 | rtc_tm.tm_hour++; | ||
141 | } | ||
142 | if (rtc_tm.tm_hour == 24) | ||
143 | rtc_tm.tm_hour = 0; | ||
144 | |||
145 | retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); | ||
146 | if (retval == -1) { | ||
147 | if (errno == ENOTTY) { | ||
148 | fprintf(stderr, | ||
149 | "\n...Alarm IRQs not supported.\n"); | ||
150 | goto test_PIE; | ||
151 | } | ||
152 | perror("RTC_ALM_SET ioctl"); | ||
153 | exit(errno); | ||
154 | } | ||
155 | |||
156 | /* Read the current alarm settings */ | ||
157 | retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); | ||
158 | if (retval == -1) { | ||
159 | perror("RTC_ALM_READ ioctl"); | ||
160 | exit(errno); | ||
161 | } | ||
162 | |||
163 | fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", | ||
164 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); | ||
165 | |||
166 | /* Enable alarm interrupts */ | ||
167 | retval = ioctl(fd, RTC_AIE_ON, 0); | ||
168 | if (retval == -1) { | ||
169 | perror("RTC_AIE_ON ioctl"); | ||
170 | exit(errno); | ||
171 | } | ||
172 | |||
173 | fprintf(stderr, "Waiting 5 seconds for alarm..."); | ||
174 | fflush(stderr); | ||
175 | /* This blocks until the alarm ring causes an interrupt */ | ||
176 | retval = read(fd, &data, sizeof(unsigned long)); | ||
177 | if (retval == -1) { | ||
178 | perror("read"); | ||
179 | exit(errno); | ||
180 | } | ||
181 | irqcount++; | ||
182 | fprintf(stderr, " okay. Alarm rang.\n"); | ||
183 | |||
184 | /* Disable alarm interrupts */ | ||
185 | retval = ioctl(fd, RTC_AIE_OFF, 0); | ||
186 | if (retval == -1) { | ||
187 | perror("RTC_AIE_OFF ioctl"); | ||
188 | exit(errno); | ||
189 | } | ||
190 | |||
191 | test_PIE: | ||
192 | /* Read periodic IRQ rate */ | ||
193 | retval = ioctl(fd, RTC_IRQP_READ, &tmp); | ||
194 | if (retval == -1) { | ||
195 | /* not all RTCs support periodic IRQs */ | ||
196 | if (errno == ENOTTY) { | ||
197 | fprintf(stderr, "\nNo periodic IRQ support\n"); | ||
198 | goto done; | ||
199 | } | ||
200 | perror("RTC_IRQP_READ ioctl"); | ||
201 | exit(errno); | ||
202 | } | ||
203 | fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); | ||
204 | |||
205 | fprintf(stderr, "Counting 20 interrupts at:"); | ||
206 | fflush(stderr); | ||
207 | |||
208 | /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ | ||
209 | for (tmp=2; tmp<=64; tmp*=2) { | ||
210 | |||
211 | retval = ioctl(fd, RTC_IRQP_SET, tmp); | ||
212 | if (retval == -1) { | ||
213 | /* not all RTCs can change their periodic IRQ rate */ | ||
214 | if (errno == ENOTTY) { | ||
215 | fprintf(stderr, | ||
216 | "\n...Periodic IRQ rate is fixed\n"); | ||
217 | goto done; | ||
218 | } | ||
219 | perror("RTC_IRQP_SET ioctl"); | ||
220 | exit(errno); | ||
221 | } | ||
222 | |||
223 | fprintf(stderr, "\n%ldHz:\t", tmp); | ||
224 | fflush(stderr); | ||
225 | |||
226 | /* Enable periodic interrupts */ | ||
227 | retval = ioctl(fd, RTC_PIE_ON, 0); | ||
228 | if (retval == -1) { | ||
229 | perror("RTC_PIE_ON ioctl"); | ||
230 | exit(errno); | ||
231 | } | ||
232 | |||
233 | for (i=1; i<21; i++) { | ||
234 | gettimeofday(&start, NULL); | ||
235 | /* This blocks */ | ||
236 | retval = read(fd, &data, sizeof(unsigned long)); | ||
237 | if (retval == -1) { | ||
238 | perror("read"); | ||
239 | exit(errno); | ||
240 | } | ||
241 | gettimeofday(&end, NULL); | ||
242 | timersub(&end, &start, &diff); | ||
243 | if (diff.tv_sec > 0 || | ||
244 | diff.tv_usec > ((1000000L / tmp) * 1.10)) { | ||
245 | fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n", | ||
246 | diff.tv_sec, diff.tv_usec, | ||
247 | (1000000L / tmp)); | ||
248 | fflush(stdout); | ||
249 | exit(-1); | ||
250 | } | ||
251 | |||
252 | fprintf(stderr, " %d",i); | ||
253 | fflush(stderr); | ||
254 | irqcount++; | ||
255 | } | ||
256 | |||
257 | /* Disable periodic interrupts */ | ||
258 | retval = ioctl(fd, RTC_PIE_OFF, 0); | ||
259 | if (retval == -1) { | ||
260 | perror("RTC_PIE_OFF ioctl"); | ||
261 | exit(errno); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | done: | ||
266 | fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); | ||
267 | |||
268 | close(fd); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
diff --git a/tools/testing/selftests/timers/set-2038.c b/tools/testing/selftests/timers/set-2038.c new file mode 100644 index 000000000000..c8a7e14446b1 --- /dev/null +++ b/tools/testing/selftests/timers/set-2038.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* Time bounds setting test | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * (C) Copyright IBM 2012 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * NOTE: This is a meta-test which sets the time to edge cases then | ||
7 | * uses other tests to detect problems. Thus this test requires that | ||
8 | * the inconsistency-check and nanosleep tests be present in the same | ||
9 | * directory it is run from. | ||
10 | * | ||
11 | * To build: | ||
12 | * $ gcc set-2038.c -o set-2038 -lrt | ||
13 | * | ||
14 | * This program is free software: you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation, either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <unistd.h> | ||
28 | #include <time.h> | ||
29 | #include <sys/time.h> | ||
30 | #ifdef KTEST | ||
31 | #include "../kselftest.h" | ||
32 | #else | ||
33 | static inline int ksft_exit_pass(void) | ||
34 | { | ||
35 | exit(0); | ||
36 | } | ||
37 | static inline int ksft_exit_fail(void) | ||
38 | { | ||
39 | exit(1); | ||
40 | } | ||
41 | #endif | ||
42 | |||
43 | #define NSEC_PER_SEC 1000000000LL | ||
44 | |||
45 | #define KTIME_MAX ((long long)~((unsigned long long)1 << 63)) | ||
46 | #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) | ||
47 | |||
48 | #define YEAR_1901 (-0x7fffffffL) | ||
49 | #define YEAR_1970 1 | ||
50 | #define YEAR_2038 0x7fffffffL /*overflows 32bit time_t */ | ||
51 | #define YEAR_2262 KTIME_SEC_MAX /*overflows 64bit ktime_t */ | ||
52 | #define YEAR_MAX ((long long)((1ULL<<63)-1)) /*overflows 64bit time_t */ | ||
53 | |||
54 | int is32bits(void) | ||
55 | { | ||
56 | return (sizeof(long) == 4); | ||
57 | } | ||
58 | |||
59 | int settime(long long time) | ||
60 | { | ||
61 | struct timeval now; | ||
62 | int ret; | ||
63 | |||
64 | now.tv_sec = (time_t)time; | ||
65 | now.tv_usec = 0; | ||
66 | |||
67 | ret = settimeofday(&now, NULL); | ||
68 | |||
69 | printf("Setting time to 0x%lx: %d\n", (long)time, ret); | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | int do_tests(void) | ||
74 | { | ||
75 | int ret; | ||
76 | |||
77 | ret = system("date"); | ||
78 | ret = system("./inconsistency-check -c 0 -t 20"); | ||
79 | ret |= system("./nanosleep"); | ||
80 | ret |= system("./nsleep-lat"); | ||
81 | return ret; | ||
82 | |||
83 | } | ||
84 | |||
85 | int main(int argc, char *argv[]) | ||
86 | { | ||
87 | int ret = 0; | ||
88 | int opt, dangerous = 0; | ||
89 | time_t start; | ||
90 | |||
91 | /* Process arguments */ | ||
92 | while ((opt = getopt(argc, argv, "d")) != -1) { | ||
93 | switch (opt) { | ||
94 | case 'd': | ||
95 | dangerous = 1; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | start = time(0); | ||
100 | |||
101 | /* First test that crazy values don't work */ | ||
102 | if (!settime(YEAR_1901)) { | ||
103 | ret = -1; | ||
104 | goto out; | ||
105 | } | ||
106 | if (!settime(YEAR_MAX)) { | ||
107 | ret = -1; | ||
108 | goto out; | ||
109 | } | ||
110 | if (!is32bits() && !settime(YEAR_2262)) { | ||
111 | ret = -1; | ||
112 | goto out; | ||
113 | } | ||
114 | |||
115 | /* Now test behavior near edges */ | ||
116 | settime(YEAR_1970); | ||
117 | ret = do_tests(); | ||
118 | if (ret) | ||
119 | goto out; | ||
120 | |||
121 | settime(YEAR_2038 - 600); | ||
122 | ret = do_tests(); | ||
123 | if (ret) | ||
124 | goto out; | ||
125 | |||
126 | /* The rest of the tests can blowup on 32bit systems */ | ||
127 | if (is32bits() && !dangerous) | ||
128 | goto out; | ||
129 | /* Test rollover behavior 32bit edge */ | ||
130 | settime(YEAR_2038 - 10); | ||
131 | ret = do_tests(); | ||
132 | if (ret) | ||
133 | goto out; | ||
134 | |||
135 | settime(YEAR_2262 - 600); | ||
136 | ret = do_tests(); | ||
137 | |||
138 | out: | ||
139 | /* restore clock */ | ||
140 | settime(start); | ||
141 | if (ret) | ||
142 | return ksft_exit_fail(); | ||
143 | return ksft_exit_pass(); | ||
144 | } | ||
diff --git a/tools/testing/selftests/timers/set-tai.c b/tools/testing/selftests/timers/set-tai.c new file mode 100644 index 000000000000..dc88dbc8831f --- /dev/null +++ b/tools/testing/selftests/timers/set-tai.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* Set tai offset | ||
2 | * by: John Stultz <john.stultz@linaro.org> | ||
3 | * (C) Copyright Linaro 2013 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * This program is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation, either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <time.h> | ||
21 | #include <sys/time.h> | ||
22 | #include <sys/timex.h> | ||
23 | #include <string.h> | ||
24 | #include <signal.h> | ||
25 | #include <unistd.h> | ||
26 | #ifdef KTEST | ||
27 | #include "../kselftest.h" | ||
28 | #else | ||
29 | static inline int ksft_exit_pass(void) | ||
30 | { | ||
31 | exit(0); | ||
32 | } | ||
33 | static inline int ksft_exit_fail(void) | ||
34 | { | ||
35 | exit(1); | ||
36 | } | ||
37 | #endif | ||
38 | |||
39 | int set_tai(int offset) | ||
40 | { | ||
41 | struct timex tx; | ||
42 | |||
43 | memset(&tx, 0, sizeof(tx)); | ||
44 | |||
45 | tx.modes = ADJ_TAI; | ||
46 | tx.constant = offset; | ||
47 | |||
48 | return adjtimex(&tx); | ||
49 | } | ||
50 | |||
51 | int get_tai(void) | ||
52 | { | ||
53 | struct timex tx; | ||
54 | |||
55 | memset(&tx, 0, sizeof(tx)); | ||
56 | |||
57 | adjtimex(&tx); | ||
58 | return tx.tai; | ||
59 | } | ||
60 | |||
61 | int main(int argc, char **argv) | ||
62 | { | ||
63 | int i, ret; | ||
64 | |||
65 | ret = get_tai(); | ||
66 | printf("tai offset started at %i\n", ret); | ||
67 | |||
68 | printf("Checking tai offsets can be properly set: "); | ||
69 | for (i = 1; i <= 60; i++) { | ||
70 | ret = set_tai(i); | ||
71 | ret = get_tai(); | ||
72 | if (ret != i) { | ||
73 | printf("[FAILED] expected: %i got %i\n", i, ret); | ||
74 | return ksft_exit_fail(); | ||
75 | } | ||
76 | } | ||
77 | printf("[OK]\n"); | ||
78 | return ksft_exit_pass(); | ||
79 | } | ||
diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c new file mode 100644 index 000000000000..4fc98c5b0899 --- /dev/null +++ b/tools/testing/selftests/timers/set-timer-lat.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* set_timer latency test | ||
2 | * John Stultz (john.stultz@linaro.org) | ||
3 | * (C) Copyright Linaro 2014 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * This test makes sure the set_timer api is correct | ||
7 | * | ||
8 | * To build: | ||
9 | * $ gcc set-timer-lat.c -o set-timer-lat -lrt | ||
10 | * | ||
11 | * This program is free software: you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | */ | ||
21 | |||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <unistd.h> | ||
25 | #include <time.h> | ||
26 | #include <string.h> | ||
27 | #include <signal.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <pthread.h> | ||
30 | #ifdef KTEST | ||
31 | #include "../kselftest.h" | ||
32 | #else | ||
33 | static inline int ksft_exit_pass(void) | ||
34 | { | ||
35 | exit(0); | ||
36 | } | ||
37 | static inline int ksft_exit_fail(void) | ||
38 | { | ||
39 | exit(1); | ||
40 | } | ||
41 | #endif | ||
42 | |||
43 | #define CLOCK_REALTIME 0 | ||
44 | #define CLOCK_MONOTONIC 1 | ||
45 | #define CLOCK_PROCESS_CPUTIME_ID 2 | ||
46 | #define CLOCK_THREAD_CPUTIME_ID 3 | ||
47 | #define CLOCK_MONOTONIC_RAW 4 | ||
48 | #define CLOCK_REALTIME_COARSE 5 | ||
49 | #define CLOCK_MONOTONIC_COARSE 6 | ||
50 | #define CLOCK_BOOTTIME 7 | ||
51 | #define CLOCK_REALTIME_ALARM 8 | ||
52 | #define CLOCK_BOOTTIME_ALARM 9 | ||
53 | #define CLOCK_HWSPECIFIC 10 | ||
54 | #define CLOCK_TAI 11 | ||
55 | #define NR_CLOCKIDS 12 | ||
56 | |||
57 | |||
58 | #define NSEC_PER_SEC 1000000000ULL | ||
59 | #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ | ||
60 | |||
61 | #define TIMER_SECS 1 | ||
62 | int alarmcount; | ||
63 | int clock_id; | ||
64 | struct timespec start_time; | ||
65 | long long max_latency_ns; | ||
66 | |||
67 | char *clockstring(int clockid) | ||
68 | { | ||
69 | switch (clockid) { | ||
70 | case CLOCK_REALTIME: | ||
71 | return "CLOCK_REALTIME"; | ||
72 | case CLOCK_MONOTONIC: | ||
73 | return "CLOCK_MONOTONIC"; | ||
74 | case CLOCK_PROCESS_CPUTIME_ID: | ||
75 | return "CLOCK_PROCESS_CPUTIME_ID"; | ||
76 | case CLOCK_THREAD_CPUTIME_ID: | ||
77 | return "CLOCK_THREAD_CPUTIME_ID"; | ||
78 | case CLOCK_MONOTONIC_RAW: | ||
79 | return "CLOCK_MONOTONIC_RAW"; | ||
80 | case CLOCK_REALTIME_COARSE: | ||
81 | return "CLOCK_REALTIME_COARSE"; | ||
82 | case CLOCK_MONOTONIC_COARSE: | ||
83 | return "CLOCK_MONOTONIC_COARSE"; | ||
84 | case CLOCK_BOOTTIME: | ||
85 | return "CLOCK_BOOTTIME"; | ||
86 | case CLOCK_REALTIME_ALARM: | ||
87 | return "CLOCK_REALTIME_ALARM"; | ||
88 | case CLOCK_BOOTTIME_ALARM: | ||
89 | return "CLOCK_BOOTTIME_ALARM"; | ||
90 | case CLOCK_TAI: | ||
91 | return "CLOCK_TAI"; | ||
92 | }; | ||
93 | return "UNKNOWN_CLOCKID"; | ||
94 | } | ||
95 | |||
96 | |||
97 | long long timespec_sub(struct timespec a, struct timespec b) | ||
98 | { | ||
99 | long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; | ||
100 | |||
101 | ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | |||
106 | void sigalarm(int signo) | ||
107 | { | ||
108 | long long delta_ns; | ||
109 | struct timespec ts; | ||
110 | |||
111 | clock_gettime(clock_id, &ts); | ||
112 | alarmcount++; | ||
113 | |||
114 | delta_ns = timespec_sub(start_time, ts); | ||
115 | delta_ns -= NSEC_PER_SEC * TIMER_SECS * alarmcount; | ||
116 | |||
117 | if (delta_ns < 0) | ||
118 | printf("%s timer fired early: FAIL\n", clockstring(clock_id)); | ||
119 | |||
120 | if (delta_ns > max_latency_ns) | ||
121 | max_latency_ns = delta_ns; | ||
122 | } | ||
123 | |||
124 | int do_timer(int clock_id, int flags) | ||
125 | { | ||
126 | struct sigevent se; | ||
127 | timer_t tm1; | ||
128 | struct itimerspec its1, its2; | ||
129 | int err; | ||
130 | |||
131 | /* Set up timer: */ | ||
132 | memset(&se, 0, sizeof(se)); | ||
133 | se.sigev_notify = SIGEV_SIGNAL; | ||
134 | se.sigev_signo = SIGRTMAX; | ||
135 | se.sigev_value.sival_int = 0; | ||
136 | |||
137 | max_latency_ns = 0; | ||
138 | alarmcount = 0; | ||
139 | |||
140 | err = timer_create(clock_id, &se, &tm1); | ||
141 | if (err) { | ||
142 | if ((clock_id == CLOCK_REALTIME_ALARM) || | ||
143 | (clock_id == CLOCK_BOOTTIME_ALARM)) { | ||
144 | printf("%-22s %s missing CAP_WAKE_ALARM? : [UNSUPPORTED]\n", | ||
145 | clockstring(clock_id), | ||
146 | flags ? "ABSTIME":"RELTIME"); | ||
147 | return 0; | ||
148 | } | ||
149 | printf("%s - timer_create() failed\n", clockstring(clock_id)); | ||
150 | return -1; | ||
151 | } | ||
152 | |||
153 | clock_gettime(clock_id, &start_time); | ||
154 | if (flags) { | ||
155 | its1.it_value = start_time; | ||
156 | its1.it_value.tv_sec += TIMER_SECS; | ||
157 | } else { | ||
158 | its1.it_value.tv_sec = TIMER_SECS; | ||
159 | its1.it_value.tv_nsec = 0; | ||
160 | } | ||
161 | its1.it_interval.tv_sec = TIMER_SECS; | ||
162 | its1.it_interval.tv_nsec = 0; | ||
163 | |||
164 | err = timer_settime(tm1, flags, &its1, &its2); | ||
165 | if (err) { | ||
166 | printf("%s - timer_settime() failed\n", clockstring(clock_id)); | ||
167 | return -1; | ||
168 | } | ||
169 | |||
170 | while (alarmcount < 5) | ||
171 | sleep(1); | ||
172 | |||
173 | printf("%-22s %s max latency: %10lld ns : ", | ||
174 | clockstring(clock_id), | ||
175 | flags ? "ABSTIME":"RELTIME", | ||
176 | max_latency_ns); | ||
177 | |||
178 | timer_delete(tm1); | ||
179 | if (max_latency_ns < UNRESONABLE_LATENCY) { | ||
180 | printf("[OK]\n"); | ||
181 | return 0; | ||
182 | } | ||
183 | printf("[FAILED]\n"); | ||
184 | return -1; | ||
185 | } | ||
186 | |||
187 | int main(void) | ||
188 | { | ||
189 | struct sigaction act; | ||
190 | int signum = SIGRTMAX; | ||
191 | int ret = 0; | ||
192 | |||
193 | /* Set up signal handler: */ | ||
194 | sigfillset(&act.sa_mask); | ||
195 | act.sa_flags = 0; | ||
196 | act.sa_handler = sigalarm; | ||
197 | sigaction(signum, &act, NULL); | ||
198 | |||
199 | printf("Setting timers for every %i seconds\n", TIMER_SECS); | ||
200 | for (clock_id = 0; clock_id < NR_CLOCKIDS; clock_id++) { | ||
201 | |||
202 | if ((clock_id == CLOCK_PROCESS_CPUTIME_ID) || | ||
203 | (clock_id == CLOCK_THREAD_CPUTIME_ID) || | ||
204 | (clock_id == CLOCK_MONOTONIC_RAW) || | ||
205 | (clock_id == CLOCK_REALTIME_COARSE) || | ||
206 | (clock_id == CLOCK_MONOTONIC_COARSE) || | ||
207 | (clock_id == CLOCK_HWSPECIFIC)) | ||
208 | continue; | ||
209 | |||
210 | ret |= do_timer(clock_id, TIMER_ABSTIME); | ||
211 | ret |= do_timer(clock_id, 0); | ||
212 | } | ||
213 | if (ret) | ||
214 | return ksft_exit_fail(); | ||
215 | return ksft_exit_pass(); | ||
216 | } | ||
diff --git a/tools/testing/selftests/timers/skew_consistency.c b/tools/testing/selftests/timers/skew_consistency.c new file mode 100644 index 000000000000..5562f84ee07c --- /dev/null +++ b/tools/testing/selftests/timers/skew_consistency.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* ADJ_FREQ Skew consistency test | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * (C) Copyright IBM 2012 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * NOTE: This is a meta-test which cranks the ADJ_FREQ knob back | ||
7 | * and forth and watches for consistency problems. Thus this test requires | ||
8 | * that the inconsistency-check tests be present in the same directory it | ||
9 | * is run from. | ||
10 | * | ||
11 | * To build: | ||
12 | * $ gcc skew_consistency.c -o skew_consistency -lrt | ||
13 | * | ||
14 | * This program is free software: you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation, either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <unistd.h> | ||
29 | #include <sys/time.h> | ||
30 | #include <sys/timex.h> | ||
31 | #include <time.h> | ||
32 | #include <sys/types.h> | ||
33 | #include <sys/stat.h> | ||
34 | #include <fcntl.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <string.h> | ||
37 | #include <sys/wait.h> | ||
38 | #ifdef KTEST | ||
39 | #include "../kselftest.h" | ||
40 | #else | ||
41 | static inline int ksft_exit_pass(void) | ||
42 | { | ||
43 | exit(0); | ||
44 | } | ||
45 | static inline int ksft_exit_fail(void) | ||
46 | { | ||
47 | exit(1); | ||
48 | } | ||
49 | #endif | ||
50 | |||
51 | #define NSEC_PER_SEC 1000000000LL | ||
52 | |||
53 | int main(int argv, char **argc) | ||
54 | { | ||
55 | struct timex tx; | ||
56 | int ret, ppm; | ||
57 | pid_t pid; | ||
58 | |||
59 | |||
60 | printf("Running Asyncrhonous Frequency Changing Tests...\n"); | ||
61 | |||
62 | pid = fork(); | ||
63 | if (!pid) | ||
64 | return system("./inconsistency-check -c 1 -t 600"); | ||
65 | |||
66 | ppm = 500; | ||
67 | ret = 0; | ||
68 | |||
69 | while (pid != waitpid(pid, &ret, WNOHANG)) { | ||
70 | ppm = -ppm; | ||
71 | tx.modes = ADJ_FREQUENCY; | ||
72 | tx.freq = ppm << 16; | ||
73 | adjtimex(&tx); | ||
74 | usleep(500000); | ||
75 | } | ||
76 | |||
77 | /* Set things back */ | ||
78 | tx.modes = ADJ_FREQUENCY; | ||
79 | tx.offset = 0; | ||
80 | adjtimex(&tx); | ||
81 | |||
82 | |||
83 | if (ret) { | ||
84 | printf("[FAILED]\n"); | ||
85 | return ksft_exit_fail(); | ||
86 | } | ||
87 | printf("[OK]\n"); | ||
88 | return ksft_exit_pass(); | ||
89 | } | ||
diff --git a/tools/testing/selftests/timers/threadtest.c b/tools/testing/selftests/timers/threadtest.c new file mode 100644 index 000000000000..e632e116f05e --- /dev/null +++ b/tools/testing/selftests/timers/threadtest.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* threadtest.c | ||
2 | * by: john stultz (johnstul@us.ibm.com) | ||
3 | * (C) Copyright IBM 2004, 2005, 2006, 2012 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * To build: | ||
7 | * $ gcc threadtest.c -o threadtest -lrt | ||
8 | * | ||
9 | * This program is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | #include <stdio.h> | ||
20 | #include <unistd.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <sys/time.h> | ||
23 | #include <pthread.h> | ||
24 | #ifdef KTEST | ||
25 | #include "../kselftest.h" | ||
26 | #else | ||
27 | static inline int ksft_exit_pass(void) | ||
28 | { | ||
29 | exit(0); | ||
30 | } | ||
31 | static inline int ksft_exit_fail(void) | ||
32 | { | ||
33 | exit(1); | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | |||
38 | /* serializes shared list access */ | ||
39 | pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; | ||
40 | /* serializes console output */ | ||
41 | pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; | ||
42 | |||
43 | |||
44 | #define MAX_THREADS 128 | ||
45 | #define LISTSIZE 128 | ||
46 | |||
47 | int done = 0; | ||
48 | |||
49 | struct timespec global_list[LISTSIZE]; | ||
50 | int listcount = 0; | ||
51 | |||
52 | |||
53 | void checklist(struct timespec *list, int size) | ||
54 | { | ||
55 | int i, j; | ||
56 | struct timespec *a, *b; | ||
57 | |||
58 | /* scan the list */ | ||
59 | for (i = 0; i < size-1; i++) { | ||
60 | a = &list[i]; | ||
61 | b = &list[i+1]; | ||
62 | |||
63 | /* look for any time inconsistencies */ | ||
64 | if ((b->tv_sec <= a->tv_sec) && | ||
65 | (b->tv_nsec < a->tv_nsec)) { | ||
66 | |||
67 | /* flag other threads */ | ||
68 | done = 1; | ||
69 | |||
70 | /*serialize printing to avoid junky output*/ | ||
71 | pthread_mutex_lock(&print_lock); | ||
72 | |||
73 | /* dump the list */ | ||
74 | printf("\n"); | ||
75 | for (j = 0; j < size; j++) { | ||
76 | if (j == i) | ||
77 | printf("---------------\n"); | ||
78 | printf("%lu:%lu\n", list[j].tv_sec, list[j].tv_nsec); | ||
79 | if (j == i+1) | ||
80 | printf("---------------\n"); | ||
81 | } | ||
82 | printf("[FAILED]\n"); | ||
83 | |||
84 | pthread_mutex_unlock(&print_lock); | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* The shared thread shares a global list | ||
90 | * that each thread fills while holding the lock. | ||
91 | * This stresses clock syncronization across cpus. | ||
92 | */ | ||
93 | void *shared_thread(void *arg) | ||
94 | { | ||
95 | while (!done) { | ||
96 | /* protect the list */ | ||
97 | pthread_mutex_lock(&list_lock); | ||
98 | |||
99 | /* see if we're ready to check the list */ | ||
100 | if (listcount >= LISTSIZE) { | ||
101 | checklist(global_list, LISTSIZE); | ||
102 | listcount = 0; | ||
103 | } | ||
104 | clock_gettime(CLOCK_MONOTONIC, &global_list[listcount++]); | ||
105 | |||
106 | pthread_mutex_unlock(&list_lock); | ||
107 | } | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | |||
112 | /* Each independent thread fills in its own | ||
113 | * list. This stresses clock_gettime() lock contention. | ||
114 | */ | ||
115 | void *independent_thread(void *arg) | ||
116 | { | ||
117 | struct timespec my_list[LISTSIZE]; | ||
118 | int count; | ||
119 | |||
120 | while (!done) { | ||
121 | /* fill the list */ | ||
122 | for (count = 0; count < LISTSIZE; count++) | ||
123 | clock_gettime(CLOCK_MONOTONIC, &my_list[count]); | ||
124 | checklist(my_list, LISTSIZE); | ||
125 | } | ||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | #define DEFAULT_THREAD_COUNT 8 | ||
130 | #define DEFAULT_RUNTIME 30 | ||
131 | |||
132 | int main(int argc, char **argv) | ||
133 | { | ||
134 | int thread_count, i; | ||
135 | time_t start, now, runtime; | ||
136 | char buf[255]; | ||
137 | pthread_t pth[MAX_THREADS]; | ||
138 | int opt; | ||
139 | void *tret; | ||
140 | int ret = 0; | ||
141 | void *(*thread)(void *) = shared_thread; | ||
142 | |||
143 | thread_count = DEFAULT_THREAD_COUNT; | ||
144 | runtime = DEFAULT_RUNTIME; | ||
145 | |||
146 | /* Process arguments */ | ||
147 | while ((opt = getopt(argc, argv, "t:n:i")) != -1) { | ||
148 | switch (opt) { | ||
149 | case 't': | ||
150 | runtime = atoi(optarg); | ||
151 | break; | ||
152 | case 'n': | ||
153 | thread_count = atoi(optarg); | ||
154 | break; | ||
155 | case 'i': | ||
156 | thread = independent_thread; | ||
157 | printf("using independent threads\n"); | ||
158 | break; | ||
159 | default: | ||
160 | printf("Usage: %s [-t <secs>] [-n <numthreads>] [-i]\n", argv[0]); | ||
161 | printf(" -t: time to run\n"); | ||
162 | printf(" -n: number of threads\n"); | ||
163 | printf(" -i: use independent threads\n"); | ||
164 | return -1; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | if (thread_count > MAX_THREADS) | ||
169 | thread_count = MAX_THREADS; | ||
170 | |||
171 | |||
172 | setbuf(stdout, NULL); | ||
173 | |||
174 | start = time(0); | ||
175 | strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&start)); | ||
176 | printf("%s\n", buf); | ||
177 | printf("Testing consistency with %i threads for %ld seconds: ", thread_count, runtime); | ||
178 | |||
179 | /* spawn */ | ||
180 | for (i = 0; i < thread_count; i++) | ||
181 | pthread_create(&pth[i], 0, thread, 0); | ||
182 | |||
183 | while (time(&now) < start + runtime) { | ||
184 | sleep(1); | ||
185 | if (done) { | ||
186 | ret = 1; | ||
187 | strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&now)); | ||
188 | printf("%s\n", buf); | ||
189 | goto out; | ||
190 | } | ||
191 | } | ||
192 | printf("[OK]\n"); | ||
193 | done = 1; | ||
194 | |||
195 | out: | ||
196 | /* wait */ | ||
197 | for (i = 0; i < thread_count; i++) | ||
198 | pthread_join(pth[i], &tret); | ||
199 | |||
200 | /* die */ | ||
201 | if (ret) | ||
202 | ksft_exit_fail(); | ||
203 | return ksft_exit_pass(); | ||
204 | } | ||
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c new file mode 100644 index 000000000000..e86d937cc22c --- /dev/null +++ b/tools/testing/selftests/timers/valid-adjtimex.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* valid adjtimex test | ||
2 | * by: John Stultz <john.stultz@linaro.org> | ||
3 | * (C) Copyright Linaro 2015 | ||
4 | * Licensed under the GPLv2 | ||
5 | * | ||
6 | * This test validates adjtimex interface with valid | ||
7 | * and invalid test data. | ||
8 | * | ||
9 | * Usage: valid-adjtimex | ||
10 | * | ||
11 | * To build: | ||
12 | * $ gcc valid-adjtimex.c -o valid-adjtimex -lrt | ||
13 | * | ||
14 | * This program is free software: you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation, either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | */ | ||
24 | |||
25 | |||
26 | |||
27 | #include <stdio.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <time.h> | ||
30 | #include <sys/time.h> | ||
31 | #include <sys/timex.h> | ||
32 | #include <string.h> | ||
33 | #include <signal.h> | ||
34 | #include <unistd.h> | ||
35 | #ifdef KTEST | ||
36 | #include "../kselftest.h" | ||
37 | #else | ||
38 | static inline int ksft_exit_pass(void) | ||
39 | { | ||
40 | exit(0); | ||
41 | } | ||
42 | static inline int ksft_exit_fail(void) | ||
43 | { | ||
44 | exit(1); | ||
45 | } | ||
46 | #endif | ||
47 | |||
48 | #define NSEC_PER_SEC 1000000000L | ||
49 | |||
50 | /* clear NTP time_status & time_state */ | ||
51 | int clear_time_state(void) | ||
52 | { | ||
53 | struct timex tx; | ||
54 | int ret; | ||
55 | |||
56 | tx.modes = ADJ_STATUS; | ||
57 | tx.status = 0; | ||
58 | ret = adjtimex(&tx); | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | #define NUM_FREQ_VALID 32 | ||
63 | #define NUM_FREQ_OUTOFRANGE 4 | ||
64 | #define NUM_FREQ_INVALID 2 | ||
65 | |||
66 | long valid_freq[NUM_FREQ_VALID] = { | ||
67 | -499<<16, | ||
68 | -450<<16, | ||
69 | -400<<16, | ||
70 | -350<<16, | ||
71 | -300<<16, | ||
72 | -250<<16, | ||
73 | -200<<16, | ||
74 | -150<<16, | ||
75 | -100<<16, | ||
76 | -75<<16, | ||
77 | -50<<16, | ||
78 | -25<<16, | ||
79 | -10<<16, | ||
80 | -5<<16, | ||
81 | -1<<16, | ||
82 | -1000, | ||
83 | 1<<16, | ||
84 | 5<<16, | ||
85 | 10<<16, | ||
86 | 25<<16, | ||
87 | 50<<16, | ||
88 | 75<<16, | ||
89 | 100<<16, | ||
90 | 150<<16, | ||
91 | 200<<16, | ||
92 | 250<<16, | ||
93 | 300<<16, | ||
94 | 350<<16, | ||
95 | 400<<16, | ||
96 | 450<<16, | ||
97 | 499<<16, | ||
98 | }; | ||
99 | |||
100 | long outofrange_freq[NUM_FREQ_OUTOFRANGE] = { | ||
101 | -1000<<16, | ||
102 | -550<<16, | ||
103 | 550<<16, | ||
104 | 1000<<16, | ||
105 | }; | ||
106 | |||
107 | #define LONG_MAX (~0UL>>1) | ||
108 | #define LONG_MIN (-LONG_MAX - 1) | ||
109 | |||
110 | long invalid_freq[NUM_FREQ_INVALID] = { | ||
111 | LONG_MAX, | ||
112 | LONG_MIN, | ||
113 | }; | ||
114 | |||
115 | int validate_freq(void) | ||
116 | { | ||
117 | struct timex tx; | ||
118 | int ret, pass = 0; | ||
119 | int i; | ||
120 | |||
121 | clear_time_state(); | ||
122 | |||
123 | memset(&tx, 0, sizeof(struct timex)); | ||
124 | /* Set the leap second insert flag */ | ||
125 | |||
126 | printf("Testing ADJ_FREQ... "); | ||
127 | for (i = 0; i < NUM_FREQ_VALID; i++) { | ||
128 | tx.modes = ADJ_FREQUENCY; | ||
129 | tx.freq = valid_freq[i]; | ||
130 | |||
131 | ret = adjtimex(&tx); | ||
132 | if (ret < 0) { | ||
133 | printf("[FAIL]\n"); | ||
134 | printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n", | ||
135 | valid_freq[i], valid_freq[i]>>16); | ||
136 | pass = -1; | ||
137 | goto out; | ||
138 | } | ||
139 | tx.modes = 0; | ||
140 | ret = adjtimex(&tx); | ||
141 | if (tx.freq != valid_freq[i]) { | ||
142 | printf("Warning: freq value %ld not what we set it (%ld)!\n", | ||
143 | tx.freq, valid_freq[i]); | ||
144 | } | ||
145 | } | ||
146 | for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) { | ||
147 | tx.modes = ADJ_FREQUENCY; | ||
148 | tx.freq = outofrange_freq[i]; | ||
149 | |||
150 | ret = adjtimex(&tx); | ||
151 | if (ret < 0) { | ||
152 | printf("[FAIL]\n"); | ||
153 | printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n", | ||
154 | outofrange_freq[i], outofrange_freq[i]>>16); | ||
155 | pass = -1; | ||
156 | goto out; | ||
157 | } | ||
158 | tx.modes = 0; | ||
159 | ret = adjtimex(&tx); | ||
160 | if (tx.freq == outofrange_freq[i]) { | ||
161 | printf("[FAIL]\n"); | ||
162 | printf("ERROR: out of range value %ld actually set!\n", | ||
163 | tx.freq); | ||
164 | pass = -1; | ||
165 | goto out; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | |||
170 | if (sizeof(long) == 8) { /* this case only applies to 64bit systems */ | ||
171 | for (i = 0; i < NUM_FREQ_INVALID; i++) { | ||
172 | tx.modes = ADJ_FREQUENCY; | ||
173 | tx.freq = invalid_freq[i]; | ||
174 | ret = adjtimex(&tx); | ||
175 | if (ret >= 0) { | ||
176 | printf("[FAIL]\n"); | ||
177 | printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n", | ||
178 | invalid_freq[i]); | ||
179 | pass = -1; | ||
180 | goto out; | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | printf("[OK]\n"); | ||
186 | out: | ||
187 | /* reset freq to zero */ | ||
188 | tx.modes = ADJ_FREQUENCY; | ||
189 | tx.freq = 0; | ||
190 | ret = adjtimex(&tx); | ||
191 | |||
192 | return pass; | ||
193 | } | ||
194 | |||
195 | |||
196 | int main(int argc, char **argv) | ||
197 | { | ||
198 | if (validate_freq()) | ||
199 | return ksft_exit_fail(); | ||
200 | |||
201 | return ksft_exit_pass(); | ||
202 | } | ||
diff --git a/tools/testing/selftests/user/Makefile b/tools/testing/selftests/user/Makefile index 12c9d15bab07..d401b63c5b1a 100644 --- a/tools/testing/selftests/user/Makefile +++ b/tools/testing/selftests/user/Makefile | |||
@@ -3,5 +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 | run_tests: all | 6 | TEST_PROGS := test_user_copy.sh |
7 | ./test_user_copy.sh | 7 | |
8 | include ../lib.mk | ||
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 077828c889f1..a5ce9534eb15 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | # Makefile for vm selftests | 1 | # Makefile for vm selftests |
2 | 2 | ||
3 | CC = $(CROSS_COMPILE)gcc | ||
4 | CFLAGS = -Wall | 3 | CFLAGS = -Wall |
5 | BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest | 4 | BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest |
6 | BINARIES += transhuge-stress | 5 | BINARIES += transhuge-stress |
@@ -9,8 +8,10 @@ all: $(BINARIES) | |||
9 | %: %.c | 8 | %: %.c |
10 | $(CC) $(CFLAGS) -o $@ $^ -lrt | 9 | $(CC) $(CFLAGS) -o $@ $^ -lrt |
11 | 10 | ||
12 | run_tests: all | 11 | TEST_PROGS := run_vmtests |
13 | @/bin/sh ./run_vmtests || (echo "vmtests: [FAIL]"; exit 1) | 12 | TEST_FILES := $(BINARIES) |
13 | |||
14 | include ../lib.mk | ||
14 | 15 | ||
15 | clean: | 16 | clean: |
16 | $(RM) $(BINARIES) | 17 | $(RM) $(BINARIES) |
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests index c87b6812300d..c87b6812300d 100644..100755 --- a/tools/testing/selftests/vm/run_vmtests +++ b/tools/testing/selftests/vm/run_vmtests | |||