Re: [PATCH 1/2] evl/sched: Add sched_out handler to sched_class
Philippe Gerum <[email protected]> Mon, 15 Jun 2026 09:29:44 +0200
| Newsgroups | dev.linux.lists.xenomai |
|---|---|
| Message-ID | <[email protected]> |
Jan Kiszka <[email protected]> writes: > On 15.06.26 09:14, Philippe Gerum wrote: >> Jan Kiszka <[email protected]> writes: >> >>> 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. >>> >> >> Your implementation needs this because the sequence is pick() -> out(), >> mine is out() -> pick(), with the latter using the budget updated by the >> former to figure out what to do next. > > But that will call out even on old == new - does not sound right. > Call to determine that next ends up being prev, then filtered out by quota_pick() as a consequence. This is strictly identical performance-wise. -- Philippe.