[LTP] [PATCH v1] Correctly handle user time in setitimer01
Cyril Hrubis
chrubis@suse.cz
Fri Nov 4 15:13:20 CET 2022
Hi!
> Since ITIMER_VIRTUAL and ITIMER_PROF are counting down in user time, we
> need to take in consideration CLOCK_MONOTONIC_COARSE resolution. This is
> requested by the syscall, since it's considering context switch from
> user to kernel mode by using a higher clock resolution.
What exactly do you mean by this? I do not think that there is "user"
and "kernel" time, just different in-kernel timers/counters with
different precisions.
As ITIMER_VIRTUAL and ITIMER_PROF counts CPU time the precision would be
the same as the COARSE clocks which depends on jiffies and on the
compile time option CONFIG_HZ. That is because in the scheduller the CPU
time is quantized into chunks based on CONFIG_HZ.
And the ITIMER_REAL runs on hrtimers which would be the same precision
as CLOCK_REALTIME or CLOCK_MONOTONIC.
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> .../kernel/syscalls/setitimer/setitimer01.c | 54 +++++++++++--------
> 1 file changed, 33 insertions(+), 21 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/setitimer/setitimer01.c b/testcases/kernel/syscalls/setitimer/setitimer01.c
> index eb62f02c6..5fcae53e8 100644
> --- a/testcases/kernel/syscalls/setitimer/setitimer01.c
> +++ b/testcases/kernel/syscalls/setitimer/setitimer01.c
> @@ -8,9 +8,16 @@
> /*\
> * [Description]
> *
> - * Spawn a child and verify that setitimer() syscall passes, and it ends up
> + * Spawn a child, verify that setitimer() syscall passes and it ends up
> * counting inside expected boundaries. Then verify from the parent that our
> * syscall sent the correct signal to the child.
> + *
> + * Boundaries are choosen accordingly with system clock. In particular, when
> + * timer counts down in real time, CLOCK_MONOTONIC resolution has taken into
> + * account as our time step. When timer counts down in user time,
> + * CLOCK_MONOTONIC_COARSE is used. The reason is that CLOCK_MONOTONIC_COARSE
> + * is our system resolution in user space, since it's taking in consideration
> + * context switches from user to kernel space.
> */
>
> #include <time.h>
> @@ -22,7 +29,6 @@
> #include "tst_safe_clocks.h"
>
> static struct itimerval *value, *ovalue;
> -static unsigned long time_step;
>
> static struct tcase {
> int which;
> @@ -55,9 +61,31 @@ static void set_setitimer_value(int usec, int o_usec)
> static void verify_setitimer(unsigned int i)
> {
> pid_t pid;
> - int status;
> - int usec = 3 * time_step;
> + struct timespec res;
> struct tcase *tc = &tcases[i];
> + int status, usec, time_step, error;
> +
> + if (tc->which == ITIMER_REAL)
> + SAFE_CLOCK_GETRES(CLOCK_MONOTONIC, &res);
> + else
> + SAFE_CLOCK_GETRES(CLOCK_MONOTONIC_COARSE, &res);
This is not going to change, so we may as well get the fine/coarse
resolution once in the test setup and initialize fine/coarse time step
once as well.
> + time_step = res.tv_nsec / 1000;
> + error = time_step;
> +
> + if (time_step <= 0) {
> + time_step = 1000;
> + error = 0;
> + }
> +
> + usec = 3 * time_step;
> +
> + tst_res(TINFO, "clock resolution: %luns, "
> + "time step: %ius, "
> + "counter time: %ius",
> + res.tv_nsec,
> + time_step,
> + usec);
>
> pid = SAFE_FORK();
>
> @@ -76,7 +104,7 @@ static void verify_setitimer(unsigned int i)
> ovalue->it_value.tv_sec,
> ovalue->it_value.tv_usec);
>
> - if (ovalue->it_value.tv_sec != 0 || ovalue->it_value.tv_usec > usec)
> + if (ovalue->it_value.tv_sec != 0 || ovalue->it_value.tv_usec > usec + error)
> tst_res(TFAIL, "Ending counters are out of range");
>
> for (;;)
> @@ -91,26 +119,10 @@ static void verify_setitimer(unsigned int i)
> tst_res(TFAIL, "Child: %s", tst_strstatus(status));
> }
>
> -static void setup(void)
> -{
> - struct timespec res;
> -
> - SAFE_CLOCK_GETRES(CLOCK_MONOTONIC, &res);
> -
> - time_step = res.tv_nsec / 1000;
> - if (time_step < 10000)
> - time_step = 10000;
> -
> - tst_res(TINFO, "clock resolution: %luns, time step: %luus",
> - res.tv_nsec,
> - time_step);
> -}
> -
> static struct tst_test test = {
> .tcnt = ARRAY_SIZE(tcases),
> .forks_child = 1,
> .test = verify_setitimer,
> - .setup = setup,
> .bufs = (struct tst_buffers[]) {
> {&value, .size = sizeof(struct itimerval)},
> {&ovalue, .size = sizeof(struct itimerval)},
> --
> 2.35.3
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
--
Cyril Hrubis
chrubis@suse.cz
More information about the ltp
mailing list