Re: [PATCH 1/2] evl/sched: Add sched_out handler to sched_class
Jan Kiszka <[email protected]> Mon, 15 Jun 2026 09:21:12 +0200
| Newsgroups | dev.linux.lists.xenomai |
|---|---|
| Message-ID | <[email protected]> |
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. Jan -- Siemens AG, Foundational Technologies Linux Expert Center