1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2013 Red Hat, Inc., Frederic Weisbecker <fweisbec@redhat.com>
4 *
5 * Selftests for a few posix timers interface.
6 *
7 * Kernel loop code stolen from Steven Rostedt <srostedt@redhat.com>
8 */
9 #define _GNU_SOURCE
10 #include <sys/time.h>
11 #include <sys/types.h>
12 #include <stdio.h>
13 #include <signal.h>
14 #include <stdint.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <time.h>
18 #include <include/vdso/time64.h>
19 #include <pthread.h>
20
21 #include "../kselftest.h"
22
23 #define DELAY 2
24
__fatal_error(const char * test,const char * name,const char * what)25 static void __fatal_error(const char *test, const char *name, const char *what)
26 {
27 char buf[64];
28 char *ret_str = NULL;
29
30 ret_str = strerror_r(errno, buf, sizeof(buf));
31
32 if (name && strlen(name) && ret_str)
33 ksft_exit_fail_msg("%s %s %s %s\n", test, name, what, ret_str);
34 else if (ret_str)
35 ksft_exit_fail_msg("%s %s %s\n", test, what, ret_str);
36 else
37 ksft_exit_fail_msg("%s %s\n", test, what);
38
39 }
40
41 #define fatal_error(name, what) __fatal_error(__func__, name, what)
42
43 static volatile int done;
44
45 /* Busy loop in userspace to elapse ITIMER_VIRTUAL */
user_loop(void)46 static void user_loop(void)
47 {
48 while (!done);
49 }
50
51 /*
52 * Try to spend as much time as possible in kernelspace
53 * to elapse ITIMER_PROF.
54 */
kernel_loop(void)55 static void kernel_loop(void)
56 {
57 void *addr = sbrk(0);
58 int err = 0;
59
60 while (!done && !err) {
61 err = brk(addr + 4096);
62 err |= brk(addr);
63 }
64 }
65
66 /*
67 * Sleep until ITIMER_REAL expiration.
68 */
idle_loop(void)69 static void idle_loop(void)
70 {
71 pause();
72 }
73
sig_handler(int nr)74 static void sig_handler(int nr)
75 {
76 done = 1;
77 }
78
79 /*
80 * Check the expected timer expiration matches the GTOD elapsed delta since
81 * we armed the timer. Keep a 0.5 sec error margin due to various jitter.
82 */
check_diff(struct timeval start,struct timeval end)83 static int check_diff(struct timeval start, struct timeval end)
84 {
85 long long diff;
86
87 diff = end.tv_usec - start.tv_usec;
88 diff += (end.tv_sec - start.tv_sec) * USEC_PER_SEC;
89
90 if (llabs(diff - DELAY * USEC_PER_SEC) > USEC_PER_SEC / 2) {
91 printf("Diff too high: %lld..", diff);
92 return -1;
93 }
94
95 return 0;
96 }
97
check_itimer(int which,const char * name)98 static void check_itimer(int which, const char *name)
99 {
100 struct timeval start, end;
101 struct itimerval val = {
102 .it_value.tv_sec = DELAY,
103 };
104
105 done = 0;
106
107 if (which == ITIMER_VIRTUAL)
108 signal(SIGVTALRM, sig_handler);
109 else if (which == ITIMER_PROF)
110 signal(SIGPROF, sig_handler);
111 else if (which == ITIMER_REAL)
112 signal(SIGALRM, sig_handler);
113
114 if (gettimeofday(&start, NULL) < 0)
115 fatal_error(name, "gettimeofday()");
116
117 if (setitimer(which, &val, NULL) < 0)
118 fatal_error(name, "setitimer()");
119
120 if (which == ITIMER_VIRTUAL)
121 user_loop();
122 else if (which == ITIMER_PROF)
123 kernel_loop();
124 else if (which == ITIMER_REAL)
125 idle_loop();
126
127 if (gettimeofday(&end, NULL) < 0)
128 fatal_error(name, "gettimeofday()");
129
130 ksft_test_result(check_diff(start, end) == 0, "%s\n", name);
131 }
132
check_timer_create(int which,const char * name)133 static void check_timer_create(int which, const char *name)
134 {
135 struct timeval start, end;
136 struct itimerspec val = {
137 .it_value.tv_sec = DELAY,
138 };
139 timer_t id;
140
141 done = 0;
142
143 if (timer_create(which, NULL, &id) < 0)
144 fatal_error(name, "timer_create()");
145
146 if (signal(SIGALRM, sig_handler) == SIG_ERR)
147 fatal_error(name, "signal()");
148
149 if (gettimeofday(&start, NULL) < 0)
150 fatal_error(name, "gettimeofday()");
151
152 if (timer_settime(id, 0, &val, NULL) < 0)
153 fatal_error(name, "timer_settime()");
154
155 user_loop();
156
157 if (gettimeofday(&end, NULL) < 0)
158 fatal_error(name, "gettimeofday()");
159
160 ksft_test_result(check_diff(start, end) == 0,
161 "timer_create() per %s\n", name);
162 }
163
164 static pthread_t ctd_thread;
165 static volatile int ctd_count, ctd_failed;
166
ctd_sighandler(int sig)167 static void ctd_sighandler(int sig)
168 {
169 if (pthread_self() != ctd_thread)
170 ctd_failed = 1;
171 ctd_count--;
172 }
173
ctd_thread_func(void * arg)174 static void *ctd_thread_func(void *arg)
175 {
176 struct itimerspec val = {
177 .it_value.tv_sec = 0,
178 .it_value.tv_nsec = 1000 * 1000,
179 .it_interval.tv_sec = 0,
180 .it_interval.tv_nsec = 1000 * 1000,
181 };
182 timer_t id;
183
184 /* 1/10 seconds to ensure the leader sleeps */
185 usleep(10000);
186
187 ctd_count = 100;
188 if (timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id))
189 fatal_error(NULL, "timer_create()");
190 if (timer_settime(id, 0, &val, NULL))
191 fatal_error(NULL, "timer_settime()");
192 while (ctd_count > 0 && !ctd_failed)
193 ;
194
195 if (timer_delete(id))
196 fatal_error(NULL, "timer_delete()");
197
198 return NULL;
199 }
200
201 /*
202 * Test that only the running thread receives the timer signal.
203 */
check_timer_distribution(void)204 static void check_timer_distribution(void)
205 {
206 if (signal(SIGALRM, ctd_sighandler) == SIG_ERR)
207 fatal_error(NULL, "signal()");
208
209 if (pthread_create(&ctd_thread, NULL, ctd_thread_func, NULL))
210 fatal_error(NULL, "pthread_create()");
211
212 if (pthread_join(ctd_thread, NULL))
213 fatal_error(NULL, "pthread_join()");
214
215 if (!ctd_failed)
216 ksft_test_result_pass("check signal distribution\n");
217 else if (ksft_min_kernel_version(6, 3))
218 ksft_test_result_fail("check signal distribution\n");
219 else
220 ksft_test_result_skip("check signal distribution (old kernel)\n");
221 }
222
223 struct tmrsig {
224 int signals;
225 int overruns;
226 };
227
siginfo_handler(int sig,siginfo_t * si,void * uc)228 static void siginfo_handler(int sig, siginfo_t *si, void *uc)
229 {
230 struct tmrsig *tsig = si ? si->si_ptr : NULL;
231
232 if (tsig) {
233 tsig->signals++;
234 tsig->overruns += si->si_overrun;
235 }
236 }
237
ignore_thread(void * arg)238 static void *ignore_thread(void *arg)
239 {
240 unsigned int *tid = arg;
241 sigset_t set;
242
243 sigemptyset(&set);
244 sigaddset(&set, SIGUSR1);
245 if (sigprocmask(SIG_BLOCK, &set, NULL))
246 fatal_error(NULL, "sigprocmask(SIG_BLOCK)");
247
248 *tid = gettid();
249 sleep(100);
250
251 if (sigprocmask(SIG_UNBLOCK, &set, NULL))
252 fatal_error(NULL, "sigprocmask(SIG_UNBLOCK)");
253 return NULL;
254 }
255
check_sig_ign(int thread)256 static void check_sig_ign(int thread)
257 {
258 struct tmrsig tsig = { };
259 struct itimerspec its;
260 unsigned int tid = 0;
261 struct sigaction sa;
262 struct sigevent sev;
263 pthread_t pthread;
264 timer_t timerid;
265 sigset_t set;
266
267 if (thread) {
268 if (pthread_create(&pthread, NULL, ignore_thread, &tid))
269 fatal_error(NULL, "pthread_create()");
270 sleep(1);
271 }
272
273 sa.sa_flags = SA_SIGINFO;
274 sa.sa_sigaction = siginfo_handler;
275 sigemptyset(&sa.sa_mask);
276 if (sigaction(SIGUSR1, &sa, NULL))
277 fatal_error(NULL, "sigaction()");
278
279 /* Block the signal */
280 sigemptyset(&set);
281 sigaddset(&set, SIGUSR1);
282 if (sigprocmask(SIG_BLOCK, &set, NULL))
283 fatal_error(NULL, "sigprocmask(SIG_BLOCK)");
284
285 memset(&sev, 0, sizeof(sev));
286 sev.sigev_notify = SIGEV_SIGNAL;
287 sev.sigev_signo = SIGUSR1;
288 sev.sigev_value.sival_ptr = &tsig;
289 if (thread) {
290 sev.sigev_notify = SIGEV_THREAD_ID;
291 sev._sigev_un._tid = tid;
292 }
293
294 if (timer_create(CLOCK_MONOTONIC, &sev, &timerid))
295 fatal_error(NULL, "timer_create()");
296
297 /* Start the timer to expire in 100ms and 100ms intervals */
298 its.it_value.tv_sec = 0;
299 its.it_value.tv_nsec = 100000000;
300 its.it_interval.tv_sec = 0;
301 its.it_interval.tv_nsec = 100000000;
302 timer_settime(timerid, 0, &its, NULL);
303
304 sleep(1);
305
306 /* Set the signal to be ignored */
307 if (signal(SIGUSR1, SIG_IGN) == SIG_ERR)
308 fatal_error(NULL, "signal(SIG_IGN)");
309
310 sleep(1);
311
312 if (thread) {
313 /* Stop the thread first. No signal should be delivered to it */
314 if (pthread_cancel(pthread))
315 fatal_error(NULL, "pthread_cancel()");
316 if (pthread_join(pthread, NULL))
317 fatal_error(NULL, "pthread_join()");
318 }
319
320 /* Restore the handler */
321 if (sigaction(SIGUSR1, &sa, NULL))
322 fatal_error(NULL, "sigaction()");
323
324 sleep(1);
325
326 /* Unblock it, which should deliver the signal in the !thread case*/
327 if (sigprocmask(SIG_UNBLOCK, &set, NULL))
328 fatal_error(NULL, "sigprocmask(SIG_UNBLOCK)");
329
330 if (timer_delete(timerid))
331 fatal_error(NULL, "timer_delete()");
332
333 if (!thread) {
334 ksft_test_result(tsig.signals == 1 && tsig.overruns == 29,
335 "check_sig_ign SIGEV_SIGNAL\n");
336 } else {
337 ksft_test_result(tsig.signals == 0 && tsig.overruns == 0,
338 "check_sig_ign SIGEV_THREAD_ID\n");
339 }
340 }
341
check_rearm(void)342 static void check_rearm(void)
343 {
344 struct tmrsig tsig = { };
345 struct itimerspec its;
346 struct sigaction sa;
347 struct sigevent sev;
348 timer_t timerid;
349 sigset_t set;
350
351 sa.sa_flags = SA_SIGINFO;
352 sa.sa_sigaction = siginfo_handler;
353 sigemptyset(&sa.sa_mask);
354 if (sigaction(SIGUSR1, &sa, NULL))
355 fatal_error(NULL, "sigaction()");
356
357 /* Block the signal */
358 sigemptyset(&set);
359 sigaddset(&set, SIGUSR1);
360 if (sigprocmask(SIG_BLOCK, &set, NULL))
361 fatal_error(NULL, "sigprocmask(SIG_BLOCK)");
362
363 memset(&sev, 0, sizeof(sev));
364 sev.sigev_notify = SIGEV_SIGNAL;
365 sev.sigev_signo = SIGUSR1;
366 sev.sigev_value.sival_ptr = &tsig;
367 if (timer_create(CLOCK_MONOTONIC, &sev, &timerid))
368 fatal_error(NULL, "timer_create()");
369
370 /* Start the timer to expire in 100ms and 100ms intervals */
371 its.it_value.tv_sec = 0;
372 its.it_value.tv_nsec = 100000000;
373 its.it_interval.tv_sec = 0;
374 its.it_interval.tv_nsec = 100000000;
375 if (timer_settime(timerid, 0, &its, NULL))
376 fatal_error(NULL, "timer_settime()");
377
378 sleep(1);
379
380 /* Reprogram the timer to single shot */
381 its.it_value.tv_sec = 10;
382 its.it_value.tv_nsec = 0;
383 its.it_interval.tv_sec = 0;
384 its.it_interval.tv_nsec = 0;
385 if (timer_settime(timerid, 0, &its, NULL))
386 fatal_error(NULL, "timer_settime()");
387
388 /* Unblock it, which should not deliver a signal */
389 if (sigprocmask(SIG_UNBLOCK, &set, NULL))
390 fatal_error(NULL, "sigprocmask(SIG_UNBLOCK)");
391
392 if (timer_delete(timerid))
393 fatal_error(NULL, "timer_delete()");
394
395 ksft_test_result(!tsig.signals, "check_rearm\n");
396 }
397
check_delete(void)398 static void check_delete(void)
399 {
400 struct tmrsig tsig = { };
401 struct itimerspec its;
402 struct sigaction sa;
403 struct sigevent sev;
404 timer_t timerid;
405 sigset_t set;
406
407 sa.sa_flags = SA_SIGINFO;
408 sa.sa_sigaction = siginfo_handler;
409 sigemptyset(&sa.sa_mask);
410 if (sigaction(SIGUSR1, &sa, NULL))
411 fatal_error(NULL, "sigaction()");
412
413 /* Block the signal */
414 sigemptyset(&set);
415 sigaddset(&set, SIGUSR1);
416 if (sigprocmask(SIG_BLOCK, &set, NULL))
417 fatal_error(NULL, "sigprocmask(SIG_BLOCK)");
418
419 memset(&sev, 0, sizeof(sev));
420 sev.sigev_notify = SIGEV_SIGNAL;
421 sev.sigev_signo = SIGUSR1;
422 sev.sigev_value.sival_ptr = &tsig;
423 if (timer_create(CLOCK_MONOTONIC, &sev, &timerid))
424 fatal_error(NULL, "timer_create()");
425
426 /* Start the timer to expire in 100ms and 100ms intervals */
427 its.it_value.tv_sec = 0;
428 its.it_value.tv_nsec = 100000000;
429 its.it_interval.tv_sec = 0;
430 its.it_interval.tv_nsec = 100000000;
431 if (timer_settime(timerid, 0, &its, NULL))
432 fatal_error(NULL, "timer_settime()");
433
434 sleep(1);
435
436 if (timer_delete(timerid))
437 fatal_error(NULL, "timer_delete()");
438
439 /* Unblock it, which should not deliver a signal */
440 if (sigprocmask(SIG_UNBLOCK, &set, NULL))
441 fatal_error(NULL, "sigprocmask(SIG_UNBLOCK)");
442
443 ksft_test_result(!tsig.signals, "check_delete\n");
444 }
445
calcdiff_ns(struct timespec t1,struct timespec t2)446 static inline int64_t calcdiff_ns(struct timespec t1, struct timespec t2)
447 {
448 int64_t diff;
449
450 diff = NSEC_PER_SEC * (int64_t)((int) t1.tv_sec - (int) t2.tv_sec);
451 diff += ((int) t1.tv_nsec - (int) t2.tv_nsec);
452 return diff;
453 }
454
check_sigev_none(int which,const char * name)455 static void check_sigev_none(int which, const char *name)
456 {
457 struct timespec start, now;
458 struct itimerspec its;
459 struct sigevent sev;
460 timer_t timerid;
461
462 memset(&sev, 0, sizeof(sev));
463 sev.sigev_notify = SIGEV_NONE;
464
465 if (timer_create(which, &sev, &timerid))
466 fatal_error(name, "timer_create()");
467
468 /* Start the timer to expire in 100ms and 100ms intervals */
469 its.it_value.tv_sec = 0;
470 its.it_value.tv_nsec = 100000000;
471 its.it_interval.tv_sec = 0;
472 its.it_interval.tv_nsec = 100000000;
473 timer_settime(timerid, 0, &its, NULL);
474
475 if (clock_gettime(which, &start))
476 fatal_error(name, "clock_gettime()");
477
478 do {
479 if (clock_gettime(which, &now))
480 fatal_error(name, "clock_gettime()");
481 } while (calcdiff_ns(now, start) < NSEC_PER_SEC);
482
483 if (timer_gettime(timerid, &its))
484 fatal_error(name, "timer_gettime()");
485
486 if (timer_delete(timerid))
487 fatal_error(name, "timer_delete()");
488
489 ksft_test_result(its.it_value.tv_sec || its.it_value.tv_nsec,
490 "check_sigev_none %s\n", name);
491 }
492
check_gettime(int which,const char * name)493 static void check_gettime(int which, const char *name)
494 {
495 struct itimerspec its, prev;
496 struct timespec start, now;
497 struct sigevent sev;
498 timer_t timerid;
499 int wraps = 0;
500 sigset_t set;
501
502 /* Block the signal */
503 sigemptyset(&set);
504 sigaddset(&set, SIGUSR1);
505 if (sigprocmask(SIG_BLOCK, &set, NULL))
506 fatal_error(name, "sigprocmask(SIG_BLOCK)");
507
508 memset(&sev, 0, sizeof(sev));
509 sev.sigev_notify = SIGEV_SIGNAL;
510 sev.sigev_signo = SIGUSR1;
511
512 if (timer_create(which, &sev, &timerid))
513 fatal_error(name, "timer_create()");
514
515 /* Start the timer to expire in 100ms and 100ms intervals */
516 its.it_value.tv_sec = 0;
517 its.it_value.tv_nsec = 100000000;
518 its.it_interval.tv_sec = 0;
519 its.it_interval.tv_nsec = 100000000;
520 if (timer_settime(timerid, 0, &its, NULL))
521 fatal_error(name, "timer_settime()");
522
523 if (timer_gettime(timerid, &prev))
524 fatal_error(name, "timer_gettime()");
525
526 if (clock_gettime(which, &start))
527 fatal_error(name, "clock_gettime()");
528
529 do {
530 if (clock_gettime(which, &now))
531 fatal_error(name, "clock_gettime()");
532 if (timer_gettime(timerid, &its))
533 fatal_error(name, "timer_gettime()");
534 if (its.it_value.tv_nsec > prev.it_value.tv_nsec)
535 wraps++;
536 prev = its;
537
538 } while (calcdiff_ns(now, start) < NSEC_PER_SEC);
539
540 if (timer_delete(timerid))
541 fatal_error(name, "timer_delete()");
542
543 ksft_test_result(wraps > 1, "check_gettime %s\n", name);
544 }
545
check_overrun(int which,const char * name)546 static void check_overrun(int which, const char *name)
547 {
548 struct timespec start, now;
549 struct tmrsig tsig = { };
550 struct itimerspec its;
551 struct sigaction sa;
552 struct sigevent sev;
553 timer_t timerid;
554 sigset_t set;
555
556 sa.sa_flags = SA_SIGINFO;
557 sa.sa_sigaction = siginfo_handler;
558 sigemptyset(&sa.sa_mask);
559 if (sigaction(SIGUSR1, &sa, NULL))
560 fatal_error(name, "sigaction()");
561
562 /* Block the signal */
563 sigemptyset(&set);
564 sigaddset(&set, SIGUSR1);
565 if (sigprocmask(SIG_BLOCK, &set, NULL))
566 fatal_error(name, "sigprocmask(SIG_BLOCK)");
567
568 memset(&sev, 0, sizeof(sev));
569 sev.sigev_notify = SIGEV_SIGNAL;
570 sev.sigev_signo = SIGUSR1;
571 sev.sigev_value.sival_ptr = &tsig;
572 if (timer_create(which, &sev, &timerid))
573 fatal_error(name, "timer_create()");
574
575 /* Start the timer to expire in 100ms and 100ms intervals */
576 its.it_value.tv_sec = 0;
577 its.it_value.tv_nsec = 100000000;
578 its.it_interval.tv_sec = 0;
579 its.it_interval.tv_nsec = 100000000;
580 if (timer_settime(timerid, 0, &its, NULL))
581 fatal_error(name, "timer_settime()");
582
583 if (clock_gettime(which, &start))
584 fatal_error(name, "clock_gettime()");
585
586 do {
587 if (clock_gettime(which, &now))
588 fatal_error(name, "clock_gettime()");
589 } while (calcdiff_ns(now, start) < NSEC_PER_SEC);
590
591 /* Unblock it, which should deliver a signal */
592 if (sigprocmask(SIG_UNBLOCK, &set, NULL))
593 fatal_error(name, "sigprocmask(SIG_UNBLOCK)");
594
595 if (timer_delete(timerid))
596 fatal_error(name, "timer_delete()");
597
598 ksft_test_result(tsig.signals == 1 && tsig.overruns == 9,
599 "check_overrun %s\n", name);
600 }
601
main(int argc,char ** argv)602 int main(int argc, char **argv)
603 {
604 ksft_print_header();
605 ksft_set_plan(18);
606
607 ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n");
608 ksft_print_msg("based timers if other threads run on the CPU...\n");
609
610 check_itimer(ITIMER_VIRTUAL, "ITIMER_VIRTUAL");
611 check_itimer(ITIMER_PROF, "ITIMER_PROF");
612 check_itimer(ITIMER_REAL, "ITIMER_REAL");
613 check_timer_create(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
614
615 /*
616 * It's unfortunately hard to reliably test a timer expiration
617 * on parallel multithread cputime. We could arm it to expire
618 * on DELAY * nr_threads, with nr_threads busy looping, then wait
619 * the normal DELAY since the time is elapsing nr_threads faster.
620 * But for that we need to ensure we have real physical free CPUs
621 * to ensure true parallelism. So test only one thread until we
622 * find a better solution.
623 */
624 check_timer_create(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
625 check_timer_distribution();
626
627 check_sig_ign(0);
628 check_sig_ign(1);
629 check_rearm();
630 check_delete();
631 check_sigev_none(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
632 check_sigev_none(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
633 check_gettime(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
634 check_gettime(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
635 check_gettime(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
636 check_overrun(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
637 check_overrun(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
638 check_overrun(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
639
640 ksft_finished();
641 }
642