From: Philippe Gerum <rpm@xenomai.org>
To: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Xenomai <xenomai@lists.linux.dev>
Subject: Re: [PATCH 1/2] evl/sched: Add sched_out handler to sched_class
Date: Mon, 15 Jun 2026 11:59:22 +0200 [thread overview]
Message-ID: <87wlw0cef9.fsf@xenomai.org> (raw)
In-Reply-To: <4797a713-e16f-4792-ab7a-51a2876fb6ef@siemens.com> (Jan Kiszka's message of "Mon, 15 Jun 2026 11:04:32 +0200")
Jan Kiszka <jan.kiszka@siemens.com> writes:
> On 15.06.26 08:42, Philippe Gerum wrote:
>> Philippe Gerum <rpm@xenomai.org> writes:
>>
>
> You also need to update tg->run_start. Otherwise, you will overcharge
> the next time this group is checked here.
>
Yes, this needs fixing.
>> + } else {
>> + tg->run_budget = 0;
>> + evl_stop_timer(&qs->limit_timer);
>> + }
>> +}
>> +
>> +static struct evl_thread *quota_pick(struct evl_rq *rq)
>> +{
>> + struct evl_thread *next, *curr = rq->curr;
>> + struct evl_sched_quota *qs = &rq->quota;
>> + struct evl_quota_group *tg;
>> +
>> pick:
>> - next = evl_get_schedq(&rq->fifo.runnable);
>> + next = evl_get_schedq(&qs->runnable);
>> if (next == NULL) {
>> evl_stop_timer(&qs->limit_timer);
>> return NULL;
>> }
>>
>> - /*
>> - * As we basically piggyback on the SCHED_FIFO runqueue, make
>> - * sure to detect non-quota threads.
>> - */
>> tg = next->quota;
>> - if (tg == NULL)
>> - return next;
>> -
>> - tg->run_start = now;
>> + tg->nr_active--;
>>
>> /*
>> * Don't consider budget if kicked, we have to allow this
>> @@ -439,25 +437,29 @@ static struct evl_thread *quota_pick(struct evl_rq *rq)
>> */
>> if (next->info & EVL_T_KICKED) {
>> evl_stop_timer(&qs->limit_timer);
>> - goto out;
>> + return next;
>> }
>>
>> + /*
>> + * __pick_next_thread() might have requeued the current
>> + * thread which is still leading the pack.
>> + */
>> + if (curr == next)
>> + return next;
>> +
>> if (ktime_to_ns(tg->run_budget) == 0) {
>> - /* Flush expired group members as we go. */
>> + /* Park expired group members as we go. */
>> list_add_tail(&next->quota_expired, &tg->expired);
>> goto pick;
>> }
>>
>> - if (otg == tg && evl_timer_is_running(&qs->limit_timer))
>> - /* Same group, leave the running timer untouched. */
>> - goto out;
>> -
>> - /* Arm limit timer for the new running group. */
>> - evl_start_timer(&qs->limit_timer,
>> - ktime_add(now, tg->run_budget),
>> - EVL_INFINITE);
>> -out:
>> - tg->nr_active--;
>> + /* Arm new limit timer on change of running group. */
>> + if (curr->quota != tg || !evl_timer_is_running(&qs->limit_timer)) {
>> + tg->run_start = evl_ktime_monotonic();
>> + evl_start_timer(&qs->limit_timer,
>> + ktime_add(tg->run_start, tg->run_budget),
>> + EVL_INFINITE);
>> + }
>
> I still don't fully get how the limit timer should be started on
> setparam over the current thread. Will curr be NULL in that case, thus
> curr != next? Is that the reason to go for a separate runqueue?
>
Nope, that one is only to make things clearer, since there is no upside
in sharing the runqueues (this was inherited from SCHED_SPORADIC for no
obvious reason with hindsight). At some point, I noticed that it would
even have introduced a bug in a previous tentative implementation using
sched_class as a discriminator between threads, to figure out whether we
should call the sched_out() handler. So, the simpler, the better:
distinct classes, distinct runqueues.
Regarding the limit timer issue, sched_pick() should not shortcut on
curr == next. IOW, the rest of the code should run even in this case. By
turning on the resched bit (which the quota_setparam() caller does), we
would end up in sched_pick() with either of those outcomes out of
quota_setparam():
- 'current' switched group, in which case we would arm a limit timer in
sched_pick() because curr->quota != next->quota (provided the shortcut
on curr == next is gone).
- 'current' stays in the same group, so the limit timer still runs unless
the budget was already fully consumed.
So I would revise my latest patch as follows:
diff --git a/kernel/evl/sched/quota.c b/kernel/evl/sched/quota.c
index 3ac650c08ccb..8f1321d46cac 100644
--- a/kernel/evl/sched/quota.c
+++ b/kernel/evl/sched/quota.c
@@ -407,6 +407,7 @@ static void quota_out(struct evl_thread *thread)
now = evl_ktime_monotonic();
consumed = ktime_sub(now, tg->run_start);
if (consumed < tg->run_budget) {
+ tg->run_start = now;
tg->run_budget = ktime_sub(tg->run_budget, consumed);
} else {
tg->run_budget = 0;
@@ -440,20 +441,13 @@ static struct evl_thread *quota_pick(struct evl_rq *rq)
return next;
}
- /*
- * __pick_next_thread() might have requeued the current
- * thread which is still leading the pack.
- */
- if (curr == next)
- return next;
-
if (ktime_to_ns(tg->run_budget) == 0) {
/* Park expired group members as we go. */
list_add_tail(&next->quota_expired, &tg->expired);
goto pick;
}
- /* Arm new limit timer on change of running group. */
+ /* Arm new limit timer if need be. */
if (curr->quota != tg || !evl_timer_is_running(&qs->limit_timer)) {
tg->run_start = evl_ktime_monotonic();
evl_start_timer(&qs->limit_timer,
>
> Looks ok otherwise, tests pass as well.
>
Uh? Ok. That was absolutely unintentional at this stage!
--
Philippe.
next prev parent reply other threads:[~2026-06-15 9:59 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-14 19:35 [PATCH 1/2] evl/sched: Add sched_out handler to sched_class Jan Kiszka
2026-06-14 19:35 ` [PATCH 2/2] evl/sched/quota: Correct budget tracking for preempted threads Jan Kiszka
2026-06-15 8:47 ` Philippe Gerum
2026-06-15 6:28 ` [PATCH 1/2] evl/sched: Add sched_out handler to sched_class Philippe Gerum
2026-06-15 6:42 ` Philippe Gerum
2026-06-15 6:44 ` Jan Kiszka
2026-06-15 6:46 ` Jan Kiszka
2026-06-15 7:14 ` Philippe Gerum
2026-06-15 7:21 ` Jan Kiszka
2026-06-15 7:29 ` Philippe Gerum
2026-06-15 6:58 ` Jan Kiszka
2026-06-15 7:17 ` Philippe Gerum
2026-06-15 7:22 ` Jan Kiszka
2026-06-15 7:30 ` Philippe Gerum
2026-06-15 7:34 ` Philippe Gerum
2026-06-15 8:34 ` Jan Kiszka
2026-06-15 8:53 ` Philippe Gerum
2026-06-15 9:02 ` Philippe Gerum
2026-06-15 8:09 ` Philippe Gerum
2026-06-15 8:40 ` Jan Kiszka
2026-06-15 8:55 ` Philippe Gerum
2026-06-15 9:04 ` Jan Kiszka
2026-06-15 9:59 ` Philippe Gerum [this message]
2026-06-15 10:24 ` Jan Kiszka
2026-06-20 15:13 ` Philippe Gerum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wlw0cef9.fsf@xenomai.org \
--to=rpm@xenomai.org \
--cc=jan.kiszka@siemens.com \
--cc=xenomai@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox