Skip to content

Commit

Permalink
sched: starvation: Autocallibrate the timeout
Browse files Browse the repository at this point in the history
Instead of hardcoding the values we attempt to measure the CPU speed and
set the runtime accordingly. Given that the difference in the duration
of the test when the kernel is buggy is about 30x we do not have to have
a precise callibration, just very rough estimate if we are running on a
server or small ARM board would suffice.

So we attempt to measure how long does a bussy loop take and base the
default timeout on that. On x86_64 CPUs the resulting runtime seems to
be between 2x and 10x of the actual runtime which seems to be in the
required range.

We also make sure to check the runtime at the end of the test because
the failures could have been masked by a timeout multiplier, i.e. if you
set LTP_TIMEOUT_MUL=10 the test would previously pass on a buggy kernel
as well. The side efect is that we now get better PASS/FAIL messages as
well.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Tested-by: Petr Vorel <pvorel@suse.cz>
Tested-by: Anders Roxell <anders.roxell@linaro.org>
  • Loading branch information
metan-ucw committed Aug 28, 2024
1 parent 66300d0 commit ec14f45
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions testcases/kernel/sched/cfs-scheduler/starvation.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,38 @@
#include <sched.h>

#include "tst_test.h"
#include "tst_safe_clocks.h"
#include "tst_timer.h"

static char *str_loop;
static long loop = 2000000;
static long loop = 1000000;
static char *str_timeout;
static int timeout = 240;
static int timeout;

#define CALLIBRATE_LOOPS 120000000

static int callibrate(void)
{
int i;
struct timespec start, stop;
long long diff;

for (i = 0; i < CALLIBRATE_LOOPS; i++)
__asm__ __volatile__ ("" : "+g" (i) : :);

SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC_RAW, &start);

for (i = 0; i < CALLIBRATE_LOOPS; i++)
__asm__ __volatile__ ("" : "+g" (i) : :);

SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC_RAW, &stop);

diff = tst_timespec_diff_us(stop, start);

tst_res(TINFO, "CPU did %i loops in %llius", CALLIBRATE_LOOPS, diff);

return diff;
}

static int wait_for_pid(pid_t pid)
{
Expand Down Expand Up @@ -78,6 +105,8 @@ static void setup(void)

if (tst_parse_int(str_timeout, &timeout, 1, INT_MAX))
tst_brk(TBROK, "Invalid number of timeout '%s'", str_timeout);
else
timeout = callibrate() / 1000;

tst_set_max_runtime(timeout);
}
Expand Down Expand Up @@ -114,7 +143,13 @@ static void do_test(void)
sleep(1);

SAFE_KILL(child_pid, SIGTERM);
TST_EXP_PASS(wait_for_pid(child_pid));

if (!tst_remaining_runtime())
tst_res(TFAIL, "Scheduller starvation reproduced.");
else
tst_res(TPASS, "Haven't reproduced scheduller starvation.");

TST_EXP_PASS_SILENT(wait_for_pid(child_pid));
}

static struct tst_test test = {
Expand Down

0 comments on commit ec14f45

Please sign in to comment.