[LTP] [PATCH V2] syscalls/timer_settime01: Make sure the timer fires

Cyril Hrubis chrubis@suse.cz
Tue Jul 7 17:02:45 CEST 2020


Hi!
> - Make sure the timer fires and catch the signals.
> 
> - Verify the values set to the itimerspec by reading them again using
>   timer_gettime() syscalls.
> 
> - Reduce the timer interval, 5 seconds was way too much.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> V1.1->V2:
> - 1/2 patch removed and solved rebase conflicts.
> 
>  .../syscalls/timer_settime/timer_settime01.c  | 70 ++++++++++++++-----
>  1 file changed, 52 insertions(+), 18 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/timer_settime/timer_settime01.c b/testcases/kernel/syscalls/timer_settime/timer_settime01.c
> index 08fb56e4943a..67769d088ab8 100644
> --- a/testcases/kernel/syscalls/timer_settime/timer_settime01.c
> +++ b/testcases/kernel/syscalls/timer_settime/timer_settime01.c
> @@ -38,28 +38,42 @@ static struct testcase {
>  	int			flag;
>  	char			*description;
>  } tcases[] = {
> -	{NULL,     5, 0, 0, "general initialization"},
> -	{&old_set, 5, 0, 0, "setting old_value"},
> -	{&old_set, 0, 5, 0, "using periodic timer"},
> -	{&old_set, 5, 0, TIMER_ABSTIME, "using absolute time"},
> +	{NULL, 1, 0, 0, "general initialization"},
> +	{&old_set, 1, 0, 0, "setting old_value"},
> +	{&old_set, 1, 1, 0, "using periodic timer"},
> +	{&old_set, 1, 0, TIMER_ABSTIME, "using absolute time"},
>  };

One second is pretty much too long as well. Can we please reduce this to
0.1s instead?

>  static struct test_variants {
> -	int (*gettime)(clockid_t clk_id, void *ts);
> -	int (*func)(timer_t timerid, int flags, void *its,
> -		    void *old_its);
> +	int (*cgettime)(clockid_t clk_id, void *ts);
> +	int (*tgettime)(timer_t timer, void *its);
> +	int (*func)(timer_t timerid, int flags, void *its, void *old_its);
>  	enum tst_ts_type type;
>  	char *desc;
>  } variants[] = {
>  #if (__NR_timer_settime != __LTP__NR_INVALID_SYSCALL)
> -	{ .gettime = sys_clock_gettime, .func = sys_timer_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
> +	{ .cgettime = sys_clock_gettime, .tgettime = sys_timer_gettime, .func = sys_timer_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
>  #endif
>  
>  #if (__NR_timer_settime64 != __LTP__NR_INVALID_SYSCALL)
> -	{ .gettime = sys_clock_gettime64, .func = sys_timer_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
> +	{ .cgettime = sys_clock_gettime64, .tgettime = sys_timer_gettime64, .func = sys_timer_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
>  #endif
>  };
>  
> +static volatile int caught_signal;
> +
> +static void clear_signal(void)
> +{
> +	/*
> +	 * The busy loop is intentional. The signal is sent after X
> +	 * seconds of CPU time has been accumulated for the process and
> +	 * thread specific clocks.
> +	 */
> +	while (!caught_signal);
> +
> +	caught_signal = 0;
> +}
> +
>  static void run(unsigned int n)
>  {
>  	struct test_variants *tv = &variants[tst_variant];
> @@ -101,7 +115,7 @@ static void run(unsigned int n)
>  
>  		if (tc->flag & TIMER_ABSTIME) {
>  			timenow.type = tv->type;
> -			if (tv->gettime(clock, tst_ts_get(&timenow)) < 0) {
> +			if (tv->cgettime(clock, tst_ts_get(&timenow)) < 0) {
>  				tst_res(TFAIL,
>  					"clock_gettime(%s) failed - skipping the test",
>  					get_clock_str(clock));
> @@ -118,23 +132,43 @@ static void run(unsigned int n)
>  		TEST(tv->func(timer, tc->flag, tst_its_get(&new_set), tst_its_get(tc->old_ptr)));
>  
>  		if (TST_RET != 0) {
> -			tst_res(TFAIL | TTERRNO, "%s failed",
> -					get_clock_str(clock));
> -		} else {
> -			tst_res(TPASS, "%s was successful",
> -					get_clock_str(clock));
> +			tst_res(TFAIL | TTERRNO, "timer_settime(%s) failed",
> +				get_clock_str(clock));
> +		}
> +
> +		TEST(tv->tgettime(timer, tst_its_get(&new_set)));
> +		if (TST_RET != 0) {
> +			tst_res(TFAIL | TTERRNO, "timer_gettime(%s) failed",
> +				get_clock_str(clock));
> +		}

If we fail here we should probably skip at least new_set checks below.

> +		if (tst_its_get_interval_sec(new_set) > tc->it_interval_tv_sec ||

The interval value should be equal to the one we have set, so we can
compare exactly.

> +		    tst_its_get_value_sec(new_set) > val) {

And the time to the next expiration is always relative, so this should
be:

		    if (value > MAX(tc->interval, tc->value))

> +			tst_res(TFAIL | TTERRNO,
> +				"timer_gettime(%s) reported bad values (%llu: %llu)",
> +				get_clock_str(clock),
> +				tst_its_get_interval_sec(new_set),
> +				tst_its_get_value_sec(new_set));
>  		}
>  
> +		clear_signal();
> +
> +		/* Wait for another event when interval was set */
> +		if (tc->it_interval_tv_sec)
> +			clear_signal();
> +
> +		tst_res(TPASS, "timer_settime(%s) passed",
> +			get_clock_str(clock));
> +
>  		TEST(tst_syscall(__NR_timer_delete, timer));
>  		if (TST_RET != 0)
>  			tst_res(TFAIL | TTERRNO, "timer_delete() failed!");
>  	}
>  }
>  
> -static void sighandler(int sig)
> +static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
>  {
> -	/* sighandler for CLOCK_*_ALARM */
> -	tst_res(TINFO, "Caught signal %s", tst_strsig(sig));
> +	caught_signal = 1;
>  }

We should check that sig has correct value as well, so I guess
that we can set caught_signal to -1 if sig != SIGARLM or something.

>  static void setup(void)
> -- 
> 2.25.0.rc1.19.g042ed3e048af
> 

-- 
Cyril Hrubis
chrubis@suse.cz


More information about the ltp mailing list