[LTP] LTP Release preparations
Li Wang
liwang@redhat.com
Thu Sep 4 04:39:03 CEST 2025
Hi Cyril, Andrea,
On Wed, Sep 3, 2025 at 9:20 PM Cyril Hrubis <chrubis@suse.cz> wrote:
> Hi!
> > > After an analysis we are now sure that it's not a product bug but a
> test
> > > issue. There might be a need to fallback the patch if we can't fix the
> > > test before release. @Li WDYT?
>
> > Try this:
> >
> > diff --git a/testcases/realtime/func/sched_football/sched_football.c
> b/testcases/realtime/func/sched_football/sched_football.c
> > index 0617bdb87..0d64210b0 100644
> > --- a/testcases/realtime/func/sched_football/sched_football.c
> > +++ b/testcases/realtime/func/sched_football/sched_football.c
> > @@ -115,8 +115,8 @@ void referee(int game_length)
> > now = start;
> >
> > /* Start the game! */
> > - tst_atomic_store(0, &the_ball);
> > pthread_barrier_wait(&start_barrier);
> > + tst_atomic_store(0, &the_ball);
> > atrace_marker_write("sched_football", "Game_started!");
> >
> >
> > We have to be sure that the defense has started before we clear the
> > ball. Previously we had the loop that waited for the players to be ready
> > before we called referee() function so all the players were ready when
> > we cleared it.
>
> Uff and we have to get the final ball position before we stop the
> threads as well, otherwise there is always chance, that we may end up
> moving the ball right after the high priority defence threads has been
> stopped:
>
This makes sense! However, from my extensive testing, I still see
occasional fails on KVM/Debug platforms.
I suspect the existing barriers ensure all threads are created before
the game starts, but small scheduler skews can still allow the attacking
thread to run for a few cycles before the defending thread migrates,
especially on debug/RT kernels.
So, based on this improve, we might need additional spin for all player
threads (offense, defense, fans) wait at the barrier and then spin until
the referee kicks off the ball.
--- a/testcases/realtime/func/sched_football/sched_football.c
+++ b/testcases/realtime/func/sched_football/sched_football.c
@@ -44,6 +44,7 @@
static tst_atomic_t the_ball;
static int players_per_team = 0;
static int game_length = DEF_GAME_LENGTH;
+static tst_atomic_t kickoff_flag;
static tst_atomic_t game_over;
static char *str_game_length;
@@ -55,6 +56,9 @@ void *thread_fan(void *arg LTP_ATTRIBUTE_UNUSED)
{
prctl(PR_SET_NAME, "crazy_fan", 0, 0, 0);
pthread_barrier_wait(&start_barrier);
+ while (!tst_atomic_load(&kickoff_flag))
+ ;
+
/*occasionally wake up and run across the field */
while (!tst_atomic_load(&game_over)) {
struct timespec start, stop;
@@ -80,6 +84,9 @@ void *thread_defense(void *arg LTP_ATTRIBUTE_UNUSED)
{
prctl(PR_SET_NAME, "defense", 0, 0, 0);
pthread_barrier_wait(&start_barrier);
+ while (!tst_atomic_load(&kickoff_flag))
+ ;
+
/*keep the ball from being moved */
while (!tst_atomic_load(&game_over)) {
}
@@ -92,6 +99,9 @@ void *thread_offense(void *arg LTP_ATTRIBUTE_UNUSED)
{
prctl(PR_SET_NAME, "offense", 0, 0, 0);
pthread_barrier_wait(&start_barrier);
+ while (!tst_atomic_load(&kickoff_flag))
+ ;
+
while (!tst_atomic_load(&game_over)) {
tst_atomic_add_return(1, &the_ball); /* move the ball ahead
one yard */
}
@@ -115,9 +125,10 @@ void referee(int game_length)
now = start;
/* Start the game! */
- tst_atomic_store(0, &the_ball);
- pthread_barrier_wait(&start_barrier);
atrace_marker_write("sched_football", "Game_started!");
+ pthread_barrier_wait(&start_barrier);
+ tst_atomic_store(0, &the_ball);
+ tst_atomic_store(1, &kickoff_flag);
/* Watch the game */
while ((now.tv_sec - start.tv_sec) < game_length) {
@@ -125,14 +136,14 @@ void referee(int game_length)
gettimeofday(&now, NULL);
}
- /* Stop the game! */
- tst_atomic_store(1, &game_over);
- atrace_marker_write("sched_football", "Game_Over!");
-
/* Blow the whistle */
final_ball = tst_atomic_load(&the_ball);
tst_res(TINFO, "Final ball position: %d", final_ball);
+ /* Stop the game! */
+ tst_atomic_store(1, &game_over);
+ atrace_marker_write("sched_football", "Game_Over!");
+
TST_EXP_EXPR(final_ball == 0);
}
@@ -154,6 +165,7 @@ static void do_test(void)
/* We're the ref, so set our priority right */
param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 80;
sched_setscheduler(0, SCHED_FIFO, ¶m);
+ tst_atomic_store(0, &kickoff_flag);
/*
* Start the offense
>
> diff --git a/testcases/realtime/func/sched_football/sched_football.c
> b/testcases/realtime/func/sched_football/sched_football.c
> index 0617bdb87..54317bed9 100644
> --- a/testcases/realtime/func/sched_football/sched_football.c
> +++ b/testcases/realtime/func/sched_football/sched_football.c
> @@ -115,8 +115,8 @@ void referee(int game_length)
> now = start;
>
> /* Start the game! */
> - tst_atomic_store(0, &the_ball);
> pthread_barrier_wait(&start_barrier);
> + tst_atomic_store(0, &the_ball);
> atrace_marker_write("sched_football", "Game_started!");
>
> /* Watch the game */
> @@ -125,14 +125,14 @@ void referee(int game_length)
> gettimeofday(&now, NULL);
> }
>
> - /* Stop the game! */
> - tst_atomic_store(1, &game_over);
> - atrace_marker_write("sched_football", "Game_Over!");
> -
> /* Blow the whistle */
> final_ball = tst_atomic_load(&the_ball);
> tst_res(TINFO, "Final ball position: %d", final_ball);
>
> + /* Stop the game! */
> + tst_atomic_store(1, &game_over);
> + atrace_marker_write("sched_football", "Game_Over!");
> +
> TST_EXP_EXPR(final_ball == 0);
> }
>
>
> --
> Cyril Hrubis
> chrubis@suse.cz
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>
--
Regards,
Li Wang
More information about the ltp
mailing list