kselftests: set-timer-lat: test one-shot timers
Subsystems (3)
cover kselftests: set-timer-lat: test one-shot timers
This patchset expands set-timer-lat to cover one-shot timers. This is inspired by a recent regression in the -stable tree, which caused one-shot alarm timers to repeat at a 1 ns interval.
The first patch adjusts how early-firing timers are reported, so faulty kernels won't cause the test to spam the console with failure messages. The second patch actually adds the one-shot testcases.
Greg Hackmann (2):
kselftests: set-timer-lat: tweak reporting when timer fires early
kselftests: set-timer-lat: add one-shot timer test cases
tools/testing/selftests/timers/set-timer-lat.c | 103 +++++++++++++++++++++---- 1 file changed, 90 insertions(+), 13 deletions(-)
Signature · 1 line
2.14.0.rc0.400.g1c36432dff-goog
PATCH 1/2 kselftests: set-timer-lat: tweak reporting when timer fires early
Rather than printing an error inside the alarm signal handler, set a flag that we check later. This keeps the test from spamming the console every time the alarm fires early. It also fixes the test exiting with error code 0 if this was the only test failure.
--- tools/testing/selftests/timers/set-timer-lat.c | 33 +++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-)
tools/testing/selftests/timers/set-timer-lat.c +25 -8
@@ -63,6 +63,7 @@ int alarmcount;int clock_id;struct timespec start_time;long long max_latency_ns; +int timer_fired_early;char *clockstring (int clockid) {
@@ -115,12 +116,19 @@ void sigalarm(int signo) delta_ns -=NSEC_PER_SEC *TIMER_SECS * alarmcount;if (delta_ns <0 ) -printf ("%s timer fired early: FAIL\n" ,clockstring (clock_id)); + timer_fired_early =1 ;if (delta_ns > max_latency_ns) max_latency_ns = delta_ns; } +void describe_timer (int flags) +{ +printf ("%-22s %s " , +clockstring (clock_id), + flags ?"ABSTIME" :"RELTIME" ); +} +int do_timer (int clock_id,int flags) {struct sigevent se;
@@ -136,6 +144,7 @@ int do_timer(int clock_id, int flags) max_latency_ns =0 ; alarmcount =0 ; + timer_fired_early =0 ; err =timer_create (clock_id, &se, &tm1);if (err) {
@@ -170,18 +179,26 @@ int do_timer(int clock_id, int flags)while (alarmcount <5 )sleep (1 ); -printf ("%-22s %s max latency: %10lld ns : " , -clockstring (clock_id), - flags ?"ABSTIME" :"RELTIME" , - max_latency_ns); +describe_timer (flags); +printf ("timer fired early: %7d : " , timer_fired_early); +if (!timer_fired_early) { +printf ("[OK]\n" ); + }else { +printf ("[FAILED]\n" ); + err =-1 ; + } + +describe_timer (flags); +printf ("max latency: %10lld ns : " , max_latency_ns);timer_delete (tm1);if (max_latency_ns <UNRESONABLE_LATENCY ) {printf ("[OK]\n" ); -return 0 ; + }else { +printf ("[FAILED]\n" ); + err =-1 ; } -printf ("[FAILED]\n" ); -return -1 ; +return err; }int main (void )
Signature · 1 line
2.14.0.rc0.400.g1c36432dff-goog
PATCH 2/2 kselftests: set-timer-lat: add one-shot timer test cases
In reply to Greg HackmannThese testcases are motivated by a recent alarmtimer regression, which caused one-shot CLOCK_{BOOTTIME,REALTIME}_ALARM timers to become periodic timers.
The new testcases are very similar to the existing testcases for repeating timers. But rather than waiting for 5 alarms, they wait for 5 seconds and verify that the alarm fired exactly once.
--- tools/testing/selftests/timers/set-timer-lat.c | 86 ++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 13 deletions(-)
tools/testing/selftests/timers/set-timer-lat.c +73 -13
@@ -20,6 +20,7 @@*/ +#include <errno.h> #include <stdio.h> #include <unistd.h> #include <time.h>
@@ -122,17 +123,17 @@ void sigalarm(int signo) max_latency_ns = delta_ns; } -void describe_timer (int flags) +void describe_timer (int flags,int interval) { -printf ("%-22s %s " , +printf ("%-22s %s %s " ,clockstring (clock_id), - flags ?"ABSTIME" :"RELTIME" ); + flags ?"ABSTIME" :"RELTIME" , + interval ?"PERIODIC" :"ONE-SHOT" ); } -int do_timer (int clock_id,int flags) +int setup_timer (int clock_id,int flags,int interval,timer_t *tm1) {struct sigevent se; -timer_t tm1;struct itimerspec its1, its2;int err;
@@ -146,7 +147,7 @@ int do_timer(int clock_id, int flags) alarmcount =0 ; timer_fired_early =0 ; - err =timer_create (clock_id, &se, &tm1); + err =timer_create (clock_id, &se, tm1);if (err) {if ((clock_id ==CLOCK_REALTIME_ALARM ) || (clock_id ==CLOCK_BOOTTIME_ALARM )) {
@@ -167,19 +168,23 @@ int do_timer(int clock_id, int flags) its1.it_value.tv_sec =TIMER_SECS ; its1.it_value.tv_nsec =0 ; } - its1.it_interval.tv_sec =TIMER_SECS ; + its1.it_interval.tv_sec = interval; its1.it_interval.tv_nsec =0 ; - err =timer_settime (tm1, flags, &its1, &its2); + err =timer_settime (*tm1, flags, &its1, &its2);if (err) {printf ("%s - timer_settime() failed\n" ,clockstring (clock_id));return -1 ; } -while (alarmcount <5 ) -sleep (1 ); +return 0 ; +} -describe_timer (flags); +int check_timer_latency (int flags,int interval) +{ +int err =0 ; + +describe_timer (flags, interval);printf ("timer fired early: %7d : " , timer_fired_early);if (!timer_fired_early) {printf ("[OK]\n" );
@@ -188,10 +193,9 @@ int do_timer(int clock_id, int flags) err =-1 ; } -describe_timer (flags); +describe_timer (flags, interval);printf ("max latency: %10lld ns : " , max_latency_ns); -timer_delete (tm1);if (max_latency_ns <UNRESONABLE_LATENCY ) {printf ("[OK]\n" ); }else {
@@ -201,6 +205,60 @@ int do_timer(int clock_id, int flags)return err; } +int check_alarmcount (int flags,int interval) +{ +describe_timer (flags, interval); +printf ("count: %19d : " , alarmcount); +if (alarmcount ==1 ) { +printf ("[OK]\n" ); +return 0 ; + } +printf ("[FAILED]\n" ); +return -1 ; +} + +int do_timer (int clock_id,int flags) +{ +timer_t tm1; +const int interval =TIMER_SECS ; +int err; + + err =setup_timer (clock_id, flags, interval, &tm1); +if (err) +return err; + +while (alarmcount <5 ) +sleep (1 ); + +timer_delete (tm1); +return check_timer_latency (flags, interval); +} + +int do_timer_oneshot (int clock_id,int flags) +{ +timer_t tm1; +const int interval =0 ; +struct timeval timeout; +fd_set fds; +int err; + + err =setup_timer (clock_id, flags, interval, &tm1); +if (err) +return err; + +memset (&timeout,0 ,sizeof (timeout)); + timeout.tv_sec =5 ; +FD_ZERO (&fds); +do { + err =select (FD_SETSIZE , &fds,NULL ,NULL , &timeout); + }while (err ==-1 && errno ==EINTR ); + +timer_delete (tm1); + err =check_timer_latency (flags, interval); + err |=check_alarmcount (flags, interval); +return err; +} +int main (void ) {struct sigaction act;
@@ -226,6 +284,8 @@ int main(void) ret |=do_timer (clock_id,TIMER_ABSTIME ); ret |=do_timer (clock_id,0 ); + ret |=do_timer_oneshot (clock_id,TIMER_ABSTIME ); + ret |=do_timer_oneshot (clock_id,0 ); }if (ret)return ksft_exit_fail ();
Signature · 1 line
2.14.0.rc0.400.g1c36432dff-goog