[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XEN PATCH v2] xen/arinc653: fix delay in the start of major frame
On 7/14/25 23:16, Anderson Choi wrote: > ARINC653 specificaion requires partition scheduling to be deterministic s/specificaion/specification/ > and periodic over time. > > However, the use of current timestamp (now) as the baseline to calculate > next_major_frame and next_switch_time introduces a delay in the start of > major frame at every period, which breaks determinism and periodicity in > partition scheduling. > > For example, we observe 3.5 msec of accumulated delay at the 21st major > frame with the following configuration. > > Target : qemuarm64 > xen version : 4.19 (43aeacff86, x86/IRQ: constrain creator-domain-ID > assertion) > dom1 : 10 msec runtime > dom2 : 10 msec runtime > > $ a653_sched -p Pool-arinc dom1:10 dom2:10 > > 0.014553536 ---x d?v? runstate_change d1v0 runnable->running //1st major > frame > 0.034629712 ---x d?v? runstate_change d1v0 runnable->running //2nd major > frame > <snip> > 0.397747008 |||x d?v? runstate_change d1v0 runnable->running //20th > major frame > 0.418066096 -||x d?v? runstate_change d1v0 runnable->running //21st > major frame > > This is due to an inherent delta between the time value the scheduler timer > is programmed to be fired with and the time value the schedule function > is executed. > > Another observation that breaks the deterministic behavior of partition > scheduling is a delayed execution of schedule(); It was called 14 msec > later than programmed. > > 1.530603952 ---x d?v? runstate_change d1v0 runnable->running > 1.564956784 --|x d?v? runstate_change d1v0 runnable->running > > Enforce the periodic behavior of partition scheduling by using the value > next_major_frame as the base to calculate the start of major frame and > the next domain switch time. > > Per discussion with Nathan Studer, there are odd cases the first minor > frame can be also missed. In that sceanario, iterate through the schedule > after resyncing s/sceanario/scenario/ > the expected next major frame. > > Signed-off-by: Anderson Choi <anderson.choi@xxxxxxxxxx> > Suggested-by: Nathan Studer <nathan.studer@xxxxxxxxxxxxxxx> I think this wants a Fixes: tag: Fixes: 22787f2e107c ("ARINC 653 scheduler") > > --- > Changes in v2: > - Changed the logic to resync major frame and to find correct > minor frame after a miss suggested by Nathan > --- > xen/common/sched/arinc653.c | 38 ++++++++++++++++++++----------------- > 1 file changed, 21 insertions(+), 17 deletions(-) > > diff --git a/xen/common/sched/arinc653.c b/xen/common/sched/arinc653.c > index 930361fa5c..a7937ed2fd 100644 > --- a/xen/common/sched/arinc653.c > +++ b/xen/common/sched/arinc653.c > @@ -526,27 +526,31 @@ a653sched_do_schedule( > > spin_lock_irqsave(&sched_priv->lock, flags); > > - if ( sched_priv->num_schedule_entries < 1 ) > - sched_priv->next_major_frame = now + DEFAULT_TIMESLICE; > - else if ( now >= sched_priv->next_major_frame ) > + /* Switch to next major frame while handling potentially missed frames */ > + while ( now >= sched_priv->next_major_frame ) > { > - /* time to enter a new major frame > - * the first time this function is called, this will be true */ > - /* start with the first domain in the schedule */ > sched_priv->sched_index = 0; > - sched_priv->next_major_frame = now + sched_priv->major_frame; > - sched_priv->next_switch_time = now + sched_priv->schedule[0].runtime; > - } > - else > - { > - while ( (now >= sched_priv->next_switch_time) && > - (sched_priv->sched_index < sched_priv->num_schedule_entries) > ) > + > + if ( sched_priv->num_schedule_entries < 1 ) > { > - /* time to switch to the next domain in this major frame */ > - sched_priv->sched_index++; > - sched_priv->next_switch_time += > - sched_priv->schedule[sched_priv->sched_index].runtime; > + sched_priv->next_major_frame += DEFAULT_TIMESLICE; > + sched_priv->next_switch_time = sched_priv->next_major_frame; > } > + else > + { > + sched_priv->next_switch_time = sched_priv->next_major_frame + > + sched_priv->schedule[0].runtime; > + sched_priv->next_major_frame += sched_priv->major_frame; > + } > + } There's no need for the above loop, this can be fixed by subtracting the remainder (modulus major_frame). E.g.: if ( now >= sched_priv->next_major_frame ) { s_time_t major_frame = sched_priv->num_schedule_entries < 1 ? DEFAULT_TIMESLICE : sched_priv->major_frame; s_time_t remainder = (now - sched_priv->next_major_frame) % major_frame; sched_priv->sched_index = 0; sched_priv->next_major_frame = now - remainder + major_frame; sched_priv->next_switch_time = now - remainder + (sched_priv->num_schedule_entries < 1 ? DEFAULT_TIMESLICE : sched_priv->schedule[0].runtime); } The commit description may want some minor updating to reflect this. > + > + /* Switch minor frame or find correct minor frame after a miss */ > + while ( (now >= sched_priv->next_switch_time) && > + (sched_priv->sched_index < sched_priv->num_schedule_entries) ) > + { > + sched_priv->sched_index++; > + sched_priv->next_switch_time += > + sched_priv->schedule[sched_priv->sched_index].runtime; > } > > /*
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |