|
[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 |