diff options
author | John Stultz <john.stultz@linaro.org> | 2015-03-11 20:40:10 -0400 |
---|---|---|
committer | Shuah Khan <shuahkh@osg.samsung.com> | 2015-03-12 15:22:15 -0400 |
commit | 7290ce1423c38108027ae90116ece6618db32bc3 (patch) | |
tree | 51fbf64da22116d7ed55f85c8234d537fdb478f4 /tools/testing/selftests/timers | |
parent | 6e8b285bcdd1834a18fd264c88a15418091c4015 (diff) |
selftests/timers: Add clocksource-switch test from timetest suite
Adds the clocksource-switch tests which continually switches the
current clocksource between all the available ones, watching for
any timekeeping inconsistencies.
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Tested-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Diffstat (limited to 'tools/testing/selftests/timers')
-rw-r--r-- | tools/testing/selftests/timers/Makefile | 3 | ||||
-rw-r--r-- | tools/testing/selftests/timers/clocksource-switch.c | 179 |
2 files changed, 181 insertions, 1 deletions
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 4b6b5c3cedaf..4a006d7ba217 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile | |||
@@ -4,7 +4,7 @@ CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) | |||
4 | LDFLAGS += -lrt -lpthread | 4 | LDFLAGS += -lrt -lpthread |
5 | bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ | 5 | bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ |
6 | set-timer-lat threadtest mqueue-lat valid-adjtimex \ | 6 | set-timer-lat threadtest mqueue-lat valid-adjtimex \ |
7 | alarmtimer-suspend change_skew skew_consistency | 7 | alarmtimer-suspend change_skew skew_consistency clocksource-switch \ |
8 | 8 | ||
9 | all: ${bins} | 9 | all: ${bins} |
10 | 10 | ||
@@ -28,6 +28,7 @@ run_destructive_tests: run_tests | |||
28 | ./valid-adjtimex | 28 | ./valid-adjtimex |
29 | ./change_skew | 29 | ./change_skew |
30 | ./skew_consistency | 30 | ./skew_consistency |
31 | ./clocksource-switch | ||
31 | 32 | ||
32 | clean: | 33 | clean: |
33 | rm -f ${bins} | 34 | rm -f ${bins} |
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 | } | ||