All of lore.kernel.org
 help / color / mirror / Atom feed
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.

  reply	other threads:[~2026-06-15  9:59 UTC|newest]

Thread overview: 24+ 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

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.