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/selftests | |
| 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/selftests')
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 | |||
