lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+GJov7j6hxp=FfupAwZZDGCXE2j3L_87D2MOCK8po5QCW83uw@mail.gmail.com>
Date: Wed, 18 Jun 2025 17:37:11 -0400
From: Rae Moar <rmoar@...gle.com>
To: David Gow <davidgow@...gle.com>
Cc: Shuah Khan <skhan@...uxfoundation.org>, Ujwal Jain <ujwaljain@...gle.com>, 
	Geert Uytterhoeven <geert@...ux-m68k.org>, linux-kernel@...r.kernel.org, 
	linux-kselftest@...r.kernel.org, kunit-dev@...glegroups.com
Subject: Re: [PATCH] kunit: Adjust kunit_test timeout based on
 test_{suite,case} speed

On Sat, Jun 14, 2025 at 4:47 AM David Gow <davidgow@...gle.com> wrote:
>
> From: Ujwal Jain <ujwaljain@...gle.com>
>
> Currently, the in-kernel kunit test case timeout is 300 seconds. (There
> is a separate timeout mechanism for the whole test execution in
> kunit.py, but that's unrelated.) However, tests marked 'slow' or 'very
> slow' may timeout, particularly on slower machines.
>
> Implement a multiplier to the test-case timeout, so that slower tests
> have longer to complete:
> - DEFAULT -> 1x default timeout
> - KUNIT_SPEED_SLOW -> 3x default timeout
> - KUNIT_SPEED_VERY_SLOW -> 12x default timeout

Hello!

This change is looking great to me. No major concerns with the code
and the tests are all passing.

Just a few thoughts: I am wondering where the multipliers of 3 and 12
came from? Are there specific tests that need those timeout amounts?
And then given this changes the behavior of tests marked as slow and
very_slow, we should update the documentation. And if possible, we
should also add tests to check this feature.

Otherwise, this looks good to me!

Thanks!
-Rae

Reviewed-by: Rae Moar <rmoar@...gle.com>

>
> A further change is planned to allow user configuration of the
> default/base timeout to allow people with faster or slower machines to
> adjust these to their use-cases.
>
> Signed-off-by: Ujwal Jain <ujwaljain@...gle.com>
> Co-developed-by: David Gow <davidgow@...gle.com>
> Signed-off-by: David Gow <davidgow@...gle.com>
> ---
>  include/kunit/try-catch.h  |  1 +
>  lib/kunit/kunit-test.c     |  9 +++++---
>  lib/kunit/test.c           | 46 ++++++++++++++++++++++++++++++++++++--
>  lib/kunit/try-catch-impl.h |  4 +++-
>  lib/kunit/try-catch.c      | 29 ++----------------------
>  5 files changed, 56 insertions(+), 33 deletions(-)
>
> diff --git a/include/kunit/try-catch.h b/include/kunit/try-catch.h
> index 7c966a1adbd3..d4e1a5b98ed6 100644
> --- a/include/kunit/try-catch.h
> +++ b/include/kunit/try-catch.h
> @@ -47,6 +47,7 @@ struct kunit_try_catch {
>         int try_result;
>         kunit_try_catch_func_t try;
>         kunit_try_catch_func_t catch;
> +       unsigned long timeout;
>         void *context;
>  };
>
> diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c
> index d9c781c859fd..387cdf7782f6 100644
> --- a/lib/kunit/kunit-test.c
> +++ b/lib/kunit/kunit-test.c
> @@ -43,7 +43,8 @@ static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test)
>         kunit_try_catch_init(try_catch,
>                              test,
>                              kunit_test_successful_try,
> -                            kunit_test_no_catch);
> +                            kunit_test_no_catch,
> +                            300 * msecs_to_jiffies(MSEC_PER_SEC));
>         kunit_try_catch_run(try_catch, test);
>
>         KUNIT_EXPECT_TRUE(test, ctx->function_called);
> @@ -75,7 +76,8 @@ static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test)
>         kunit_try_catch_init(try_catch,
>                              test,
>                              kunit_test_unsuccessful_try,
> -                            kunit_test_catch);
> +                            kunit_test_catch,
> +                            300 * msecs_to_jiffies(MSEC_PER_SEC));
>         kunit_try_catch_run(try_catch, test);
>
>         KUNIT_EXPECT_TRUE(test, ctx->function_called);
> @@ -129,7 +131,8 @@ static void kunit_test_fault_null_dereference(struct kunit *test)
>         kunit_try_catch_init(try_catch,
>                              test,
>                              kunit_test_null_dereference,
> -                            kunit_test_catch);
> +                            kunit_test_catch,
> +                            300 * msecs_to_jiffies(MSEC_PER_SEC));
>         kunit_try_catch_run(try_catch, test);
>
>         KUNIT_EXPECT_EQ(test, try_catch->try_result, -EINTR);
> diff --git a/lib/kunit/test.c b/lib/kunit/test.c
> index 146d1b48a096..002121675605 100644
> --- a/lib/kunit/test.c
> +++ b/lib/kunit/test.c
> @@ -373,6 +373,46 @@ static void kunit_run_case_check_speed(struct kunit *test,
>                    duration.tv_sec, duration.tv_nsec);
>  }
>
> +/* Returns timeout multiplier based on speed.
> + * DEFAULT:                1
> + * KUNIT_SPEED_SLOW:        3
> + * KUNIT_SPEED_VERY_SLOW:   12
> + */
> +static int kunit_timeout_mult(enum kunit_speed speed)
> +{
> +       switch (speed) {
> +       case KUNIT_SPEED_SLOW:
> +               return 3;
> +       case KUNIT_SPEED_VERY_SLOW:
> +               return 12;
> +       default:
> +               return 1;
> +       }
> +}
> +
> +static unsigned long kunit_test_timeout(struct kunit_suite *suite, struct kunit_case *test_case)
> +{
> +       int mult = 1;
> +       /*
> +        * TODO: Make the default (base) timeout configurable, so that users with
> +        * particularly slow or fast machines can successfully run tests, while
> +        * still taking advantage of the relative speed.
> +        */
> +       unsigned long default_timeout = 300;
> +
> +       /*
> +        * The default test timeout is 300 seconds and will be adjusted by mult
> +        * based on the test speed. The test speed will be overridden by the
> +        * innermost test component.
> +        */
> +       if (suite->attr.speed != KUNIT_SPEED_UNSET)
> +               mult = kunit_timeout_mult(suite->attr.speed);
> +       if (test_case->attr.speed != KUNIT_SPEED_UNSET)
> +               mult = kunit_timeout_mult(test_case->attr.speed);
> +       return mult * default_timeout * msecs_to_jiffies(MSEC_PER_SEC);
> +}
> +
> +
>  /*
>   * Initializes and runs test case. Does not clean up or do post validations.
>   */
> @@ -527,7 +567,8 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
>         kunit_try_catch_init(try_catch,
>                              test,
>                              kunit_try_run_case,
> -                            kunit_catch_run_case);
> +                            kunit_catch_run_case,
> +                            kunit_test_timeout(suite, test_case));
>         context.test = test;
>         context.suite = suite;
>         context.test_case = test_case;
> @@ -537,7 +578,8 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
>         kunit_try_catch_init(try_catch,
>                              test,
>                              kunit_try_run_case_cleanup,
> -                            kunit_catch_run_case_cleanup);
> +                            kunit_catch_run_case_cleanup,
> +                            kunit_test_timeout(suite, test_case));
>         kunit_try_catch_run(try_catch, &context);
>
>         /* Propagate the parameter result to the test case. */
> diff --git a/lib/kunit/try-catch-impl.h b/lib/kunit/try-catch-impl.h
> index 203ba6a5e740..6f401b97cd0b 100644
> --- a/lib/kunit/try-catch-impl.h
> +++ b/lib/kunit/try-catch-impl.h
> @@ -17,11 +17,13 @@ struct kunit;
>  static inline void kunit_try_catch_init(struct kunit_try_catch *try_catch,
>                                         struct kunit *test,
>                                         kunit_try_catch_func_t try,
> -                                       kunit_try_catch_func_t catch)
> +                                       kunit_try_catch_func_t catch,
> +                                       unsigned long timeout)
>  {
>         try_catch->test = test;
>         try_catch->try = try;
>         try_catch->catch = catch;
> +       try_catch->timeout = timeout;
>  }
>
>  #endif /* _KUNIT_TRY_CATCH_IMPL_H */
> diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
> index 6bbe0025b079..d84a879f0a78 100644
> --- a/lib/kunit/try-catch.c
> +++ b/lib/kunit/try-catch.c
> @@ -34,31 +34,6 @@ static int kunit_generic_run_threadfn_adapter(void *data)
>         return 0;
>  }
>
> -static unsigned long kunit_test_timeout(void)
> -{
> -       /*
> -        * TODO(brendanhiggins@...gle.com): We should probably have some type of
> -        * variable timeout here. The only question is what that timeout value
> -        * should be.
> -        *
> -        * The intention has always been, at some point, to be able to label
> -        * tests with some type of size bucket (unit/small, integration/medium,
> -        * large/system/end-to-end, etc), where each size bucket would get a
> -        * default timeout value kind of like what Bazel does:
> -        * https://docs.bazel.build/versions/master/be/common-definitions.html#test.size
> -        * There is still some debate to be had on exactly how we do this. (For
> -        * one, we probably want to have some sort of test runner level
> -        * timeout.)
> -        *
> -        * For more background on this topic, see:
> -        * https://mike-bland.com/2011/11/01/small-medium-large.html
> -        *
> -        * If tests timeout due to exceeding sysctl_hung_task_timeout_secs,
> -        * the task will be killed and an oops generated.
> -        */
> -       return 300 * msecs_to_jiffies(MSEC_PER_SEC); /* 5 min */
> -}
> -
>  void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
>  {
>         struct kunit *test = try_catch->test;
> @@ -85,8 +60,8 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
>         task_done = task_struct->vfork_done;
>         wake_up_process(task_struct);
>
> -       time_remaining = wait_for_completion_timeout(task_done,
> -                                                    kunit_test_timeout());
> +       time_remaining = wait_for_completion_timeout(
> +               task_done, try_catch->timeout);
>         if (time_remaining == 0) {
>                 try_catch->try_result = -ETIMEDOUT;
>                 kthread_stop(task_struct);
> --
> 2.50.0.rc1.591.g9c95f17f64-goog
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ