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