Re: [PATCH 1/2] evl/sched: Add sched_out handler to sched_class

Jan Kiszka <[email protected]> Mon, 15 Jun 2026 08:46:34 +0200
Newsgroups dev.linux.lists.xenomai
Message-ID <[email protected]>
On 15.06.26 08:42, Philippe Gerum wrote:
> Philippe Gerum <[email protected]> writes:
> 
>> Jan Kiszka <[email protected]> writes:
>>
>>> From: Jan Kiszka <[email protected]>
>>>
>>> This shall be invoked before a thread switch, providing both the current
>>> and the next thread as arguments. Some scheduling classes may need it to
>>> correctly handle their state as the sched_pick may not be invoked when a
>>> higher-weighted class is providing the next thread.
>>>
>>> Signed-off-by: Jan Kiszka <[email protected]>
>>> ---
>>>  include/evl/sched.h     | 2 ++
>>>  kernel/evl/sched/core.c | 5 +++++
>>>  2 files changed, 7 insertions(+)
>>>
>>> diff --git a/include/evl/sched.h b/include/evl/sched.h
>>> index ae9690860146c..0b16f1b1cf626 100644
>>> --- a/include/evl/sched.h
>>> +++ b/include/evl/sched.h
>>> @@ -120,6 +120,8 @@ struct evl_sched_class {
>>>  	void (*sched_dequeue)(struct evl_thread *thread);
>>>  	void (*sched_requeue)(struct evl_thread *thread);
>>>  	struct evl_thread *(*sched_pick)(struct evl_rq *rq);
>>> +	void (*sched_out)(struct evl_thread *thread,
>>> +			  struct evl_thread *next);
>>>  	void (*sched_yield)(struct evl_thread *thread);
>>>  	void (*sched_migrate)(struct evl_thread *thread,
>>>  			      struct evl_rq *rq);
>>> diff --git a/kernel/evl/sched/core.c b/kernel/evl/sched/core.c
>>> index eb133e334d30f..0d49fc16bd67e 100644
>>> --- a/kernel/evl/sched/core.c
>>> +++ b/kernel/evl/sched/core.c
>>> @@ -910,6 +910,7 @@ static __always_inline bool test_resched(struct evl_rq *this_rq)
>>>   */
>>>  void __evl_schedule(void) /* oob or/and hard irqs off (CPU migration-safe) */
>>>  {
>>> +	struct evl_sched_class *prev_schedclass;
>>>  	struct evl_rq *this_rq = this_evl_rq();
>>>  	struct evl_thread *prev, *next, *curr;
>>>  	bool leaving_inband, inband_tail;
>>> @@ -990,6 +991,10 @@ void __evl_schedule(void) /* oob or/and hard irqs off (CPU migration-safe) */
>>>  	this_rq->curr = next;
>>>  	leaving_inband = false;
>>>  
>>> +	prev_schedclass = prev->sched_class;
>>> +	if (prev_schedclass->sched_out)
>>> +		prev_schedclass->sched_out(prev, next);
>>> +
>>>  	/*
>>>  	 * Careful: we _must_ have updated this_rq->curr before
>>>  	 * performing the rest of the context switch code
>>
>> I've been working on this lately too. It turns out that we need more
>> than this, although this is definitely part of the solution. I'll follow
>> up on this issue.
> 
> This is still wip, I'm sharing this early to discuss details for
> reconciling both proposals (the hunk in __evl_schedule() is merely
> cosmetic, no functional change).
> 
> commit f49dbd63c1389a6b99508ef0da852545b102d1cc (HEAD -> wip/fix-quota-sched)
> Author: Philippe Gerum <[email protected]>
> Date:   Sun Jun 14 12:08:59 2026 +0200
> 
>     evl: sched/quota: fix budget tracking on preemption
>     
>     Upon preemption of a SCHED_QUOTA thread by a SCHED_FIFO one, the
>     runtime budget of the former is inaccurately tracked. This is due to
>     the fifo->pick() handler returning a valid thread, which prevents the
>     quota->pick() handler from being called. As a result, the last runtime
>     period of the outgoing thread is not accounted for.
>     
>     To fix this, we introduce a new sched_out() handler which is called
>     for the outgoing thread, which the quota policy uses to update the
>     remaining budget of preempted threads appropriately. In addition, the
>     implementation no longer shares the runnable thread queue with
>     SCHED_FIFO.
>     
>     Signed-off-by: Philippe Gerum <[email protected]>
> 
> diff --git a/include/evl/sched.h b/include/evl/sched.h
> index ae9690860146..cc824c28004b 100644
> --- a/include/evl/sched.h
> +++ b/include/evl/sched.h
> @@ -120,6 +120,7 @@ struct evl_sched_class {
>  	void (*sched_dequeue)(struct evl_thread *thread);
>  	void (*sched_requeue)(struct evl_thread *thread);
>  	struct evl_thread *(*sched_pick)(struct evl_rq *rq);
> +	void (*sched_out)(struct evl_thread *thread);

The out handler also needs the target thread in order to identify if
there is a tg change or not.

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center