[LTP] [PATCH v2] sched_football: synchronize with kickoff flag to reduce skew
Li Wang
liwang@redhat.com
Fri Sep 5 16:48:41 CEST 2025
On Fri, Sep 5, 2025 at 9:44 PM Cyril Hrubis <chrubis@suse.cz> wrote:
> Hi!
> > Thanks, I do manually test and now almost 1/20 times fail.
> > And the worth mentioning that this is not a new failure in RHEL kernels.
> > Those patches since the barrier have already much improved the test
> > result from RHEL side. At least from RHEL RT-kernel I didn't observe
> > fail any more.
> >
> > So ,as long as the patch works on the SUSE kernel to resolve it's NEW
> > problem,
> > I think we can merge.
>
> I got another idea meanwhile, what happens if we keep bussy loop for the
> defense and add the sched_yield() only to offense and crazy fans? That
> should ensure that before the kickoff the defense threads should be
> hogging the available CPUs.
>
Sounds great, or something we can do more, maybe remove the busy-loop
from the crazy-fan threads, since the fan threads are the distraction
during the
game so we don't need to have them waking up so early in the first place.
With those refined, I would not get fails on RHEL non-RT kernel anymore,
I will keep the sched_football test run more than 10000 times tonight.
` for i in {1..10000}; do ./sched_football ; done`
If everything goes well, I will sign off patch v3 as below:
--- 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;
@@ -80,6 +81,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 +96,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))
+ sched_yield();
+
while (!tst_atomic_load(&game_over)) {
tst_atomic_add_return(1, &the_ball); /* move the ball ahead
one yard */
}
@@ -115,9 +122,16 @@ 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);
+ usleep(200000);
+
+ tst_atomic_store(0, &the_ball);
+ tst_atomic_store(1, &kickoff_flag);
+ if (tst_check_preempt_rt())
+ usleep(20000);
+ else
+ usleep(2000000);
/* Watch the game */
while ((now.tv_sec - start.tv_sec) < game_length) {
@@ -125,14 +139,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 +168,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
--
Regards,
Li Wang
More information about the ltp
mailing list