aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 21:57:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 21:57:44 -0400
commit43224b96af3154cedd7220f7b90094905f07ac78 (patch)
tree44279acc4613b314ff031620fd62641db3c85b71 /tools
parentd70b3ef54ceaf1c7c92209f5a662a670d04cbed9 (diff)
parent1cb6c2151850584ee805fdcf088af0bb81f4b086 (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "A rather largish update for everything time and timer related: - Cache footprint optimizations for both hrtimers and timer wheel - Lower the NOHZ impact on systems which have NOHZ or timer migration disabled at runtime. - Optimize run time overhead of hrtimer interrupt by making the clock offset updates smarter - hrtimer cleanups and removal of restrictions to tackle some problems in sched/perf - Some more leap second tweaks - Another round of changes addressing the 2038 problem - First step to change the internals of clock event devices by introducing the necessary infrastructure - Allow constant folding for usecs/msecs_to_jiffies() - The usual pile of clockevent/clocksource driver updates The hrtimer changes contain updates to sched, perf and x86 as they depend on them plus changes all over the tree to cleanup API changes and redundant code, which got copied all over the place. The y2038 changes touch s390 to remove the last non 2038 safe code related to boot/persistant clock" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (114 commits) clocksource: Increase dependencies of timer-stm32 to limit build wreckage timer: Minimize nohz off overhead timer: Reduce timer migration overhead if disabled timer: Stats: Simplify the flags handling timer: Replace timer base by a cpu index timer: Use hlist for the timer wheel hash buckets timer: Remove FIFO "guarantee" timers: Sanitize catchup_timer_jiffies() usage hrtimer: Allow hrtimer::function() to free the timer seqcount: Introduce raw_write_seqcount_barrier() seqcount: Rename write_seqcount_barrier() hrtimer: Fix hrtimer_is_queued() hole hrtimer: Remove HRTIMER_STATE_MIGRATE selftest: Timers: Avoid signal deadlock in leap-a-day timekeeping: Copy the shadow-timekeeper over the real timekeeper last clockevents: Check state instead of mode in suspend/resume path selftests: timers: Add leap-second timer edge testing to leap-a-day.c ntp: Do leapsecond adjustment in adjtimex read path time: Prevent early expiry of hrtimers[CLOCK_REALTIME] at the leap second edge ntp: Introduce and use SECS_PER_DAY macro instead of 86400 ...
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/timers/leap-a-day.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/tools/testing/selftests/timers/leap-a-day.c b/tools/testing/selftests/timers/leap-a-day.c
index b8272e6c4b3b..fb46ad6ac92c 100644
--- a/tools/testing/selftests/timers/leap-a-day.c
+++ b/tools/testing/selftests/timers/leap-a-day.c
@@ -44,6 +44,7 @@
44#include <time.h> 44#include <time.h>
45#include <sys/time.h> 45#include <sys/time.h>
46#include <sys/timex.h> 46#include <sys/timex.h>
47#include <sys/errno.h>
47#include <string.h> 48#include <string.h>
48#include <signal.h> 49#include <signal.h>
49#include <unistd.h> 50#include <unistd.h>
@@ -63,6 +64,9 @@ static inline int ksft_exit_fail(void)
63#define NSEC_PER_SEC 1000000000ULL 64#define NSEC_PER_SEC 1000000000ULL
64#define CLOCK_TAI 11 65#define CLOCK_TAI 11
65 66
67time_t next_leap;
68int error_found;
69
66/* returns 1 if a <= b, 0 otherwise */ 70/* returns 1 if a <= b, 0 otherwise */
67static inline int in_order(struct timespec a, struct timespec b) 71static inline int in_order(struct timespec a, struct timespec b)
68{ 72{
@@ -134,6 +138,35 @@ void handler(int unused)
134 exit(0); 138 exit(0);
135} 139}
136 140
141void sigalarm(int signo)
142{
143 struct timex tx;
144 int ret;
145
146 tx.modes = 0;
147 ret = adjtimex(&tx);
148
149 if (tx.time.tv_sec < next_leap) {
150 printf("Error: Early timer expiration! (Should be %ld)\n", next_leap);
151 error_found = 1;
152 printf("adjtimex: %10ld sec + %6ld us (%i)\t%s\n",
153 tx.time.tv_sec,
154 tx.time.tv_usec,
155 tx.tai,
156 time_state_str(ret));
157 }
158 if (ret != TIME_WAIT) {
159 printf("Error: Timer seeing incorrect NTP state? (Should be TIME_WAIT)\n");
160 error_found = 1;
161 printf("adjtimex: %10ld sec + %6ld us (%i)\t%s\n",
162 tx.time.tv_sec,
163 tx.time.tv_usec,
164 tx.tai,
165 time_state_str(ret));
166 }
167}
168
169
137/* Test for known hrtimer failure */ 170/* Test for known hrtimer failure */
138void test_hrtimer_failure(void) 171void test_hrtimer_failure(void)
139{ 172{
@@ -144,12 +177,19 @@ void test_hrtimer_failure(void)
144 clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &target, NULL); 177 clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &target, NULL);
145 clock_gettime(CLOCK_REALTIME, &now); 178 clock_gettime(CLOCK_REALTIME, &now);
146 179
147 if (!in_order(target, now)) 180 if (!in_order(target, now)) {
148 printf("ERROR: hrtimer early expiration failure observed.\n"); 181 printf("ERROR: hrtimer early expiration failure observed.\n");
182 error_found = 1;
183 }
149} 184}
150 185
151int main(int argc, char **argv) 186int main(int argc, char **argv)
152{ 187{
188 timer_t tm1;
189 struct itimerspec its1;
190 struct sigevent se;
191 struct sigaction act;
192 int signum = SIGRTMAX;
153 int settime = 0; 193 int settime = 0;
154 int tai_time = 0; 194 int tai_time = 0;
155 int insert = 1; 195 int insert = 1;
@@ -191,6 +231,12 @@ int main(int argc, char **argv)
191 signal(SIGINT, handler); 231 signal(SIGINT, handler);
192 signal(SIGKILL, handler); 232 signal(SIGKILL, handler);
193 233
234 /* Set up timer signal handler: */
235 sigfillset(&act.sa_mask);
236 act.sa_flags = 0;
237 act.sa_handler = sigalarm;
238 sigaction(signum, &act, NULL);
239
194 if (iterations < 0) 240 if (iterations < 0)
195 printf("This runs continuously. Press ctrl-c to stop\n"); 241 printf("This runs continuously. Press ctrl-c to stop\n");
196 else 242 else
@@ -201,7 +247,7 @@ int main(int argc, char **argv)
201 int ret; 247 int ret;
202 struct timespec ts; 248 struct timespec ts;
203 struct timex tx; 249 struct timex tx;
204 time_t now, next_leap; 250 time_t now;
205 251
206 /* Get the current time */ 252 /* Get the current time */
207 clock_gettime(CLOCK_REALTIME, &ts); 253 clock_gettime(CLOCK_REALTIME, &ts);
@@ -251,10 +297,27 @@ int main(int argc, char **argv)
251 297
252 printf("Scheduling leap second for %s", ctime(&next_leap)); 298 printf("Scheduling leap second for %s", ctime(&next_leap));
253 299
300 /* Set up timer */
301 printf("Setting timer for %ld - %s", next_leap, ctime(&next_leap));
302 memset(&se, 0, sizeof(se));
303 se.sigev_notify = SIGEV_SIGNAL;
304 se.sigev_signo = signum;
305 se.sigev_value.sival_int = 0;
306 if (timer_create(CLOCK_REALTIME, &se, &tm1) == -1) {
307 printf("Error: timer_create failed\n");
308 return ksft_exit_fail();
309 }
310 its1.it_value.tv_sec = next_leap;
311 its1.it_value.tv_nsec = 0;
312 its1.it_interval.tv_sec = 0;
313 its1.it_interval.tv_nsec = 0;
314 timer_settime(tm1, TIMER_ABSTIME, &its1, NULL);
315
254 /* Wake up 3 seconds before leap */ 316 /* Wake up 3 seconds before leap */
255 ts.tv_sec = next_leap - 3; 317 ts.tv_sec = next_leap - 3;
256 ts.tv_nsec = 0; 318 ts.tv_nsec = 0;
257 319
320
258 while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL)) 321 while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL))
259 printf("Something woke us up, returning to sleep\n"); 322 printf("Something woke us up, returning to sleep\n");
260 323
@@ -276,6 +339,7 @@ int main(int argc, char **argv)
276 while (now < next_leap + 2) { 339 while (now < next_leap + 2) {
277 char buf[26]; 340 char buf[26];
278 struct timespec tai; 341 struct timespec tai;
342 int ret;
279 343
280 tx.modes = 0; 344 tx.modes = 0;
281 ret = adjtimex(&tx); 345 ret = adjtimex(&tx);
@@ -308,8 +372,13 @@ int main(int argc, char **argv)
308 /* Note if kernel has known hrtimer failure */ 372 /* Note if kernel has known hrtimer failure */
309 test_hrtimer_failure(); 373 test_hrtimer_failure();
310 374
311 printf("Leap complete\n\n"); 375 printf("Leap complete\n");
312 376 if (error_found) {
377 printf("Errors observed\n");
378 clear_time_state();
379 return ksft_exit_fail();
380 }
381 printf("\n");
313 if ((iterations != -1) && !(--iterations)) 382 if ((iterations != -1) && !(--iterations))
314 break; 383 break;
315 } 384 }