From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752311AbdHRSvV (ORCPT ); Fri, 18 Aug 2017 14:51:21 -0400 Received: from mail-pg0-f41.google.com ([74.125.83.41]:37293 "EHLO mail-pg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752185AbdHRSvP (ORCPT ); Fri, 18 Aug 2017 14:51:15 -0400 From: John Stultz To: lkml Cc: Greg Hackmann , Thomas Gleixner , Ingo Molnar , Miroslav Lichvar , Richard Cochran , Prarit Bhargava , Stephen Boyd , Shuah Khan , linux-kselftest@vger.kernel.org, John Stultz Subject: [PATCH 4/6] kselftests: timers: set-timer-lat: Add one-shot timer test cases Date: Fri, 18 Aug 2017 11:51:00 -0700 Message-Id: <1503082262-29450-5-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503082262-29450-1-git-send-email-john.stultz@linaro.org> References: <1503082262-29450-1-git-send-email-john.stultz@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Greg Hackmann These 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. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Miroslav Lichvar Cc: Richard Cochran Cc: Prarit Bhargava Cc: Stephen Boyd Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Greg Hackmann Signed-off-by: John Stultz --- tools/testing/selftests/timers/set-timer-lat.c | 86 ++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c index 10c2e18..15434da 100644 --- a/tools/testing/selftests/timers/set-timer-lat.c +++ b/tools/testing/selftests/timers/set-timer-lat.c @@ -20,6 +20,7 @@ */ +#include #include #include #include @@ -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(); -- 2.7.4