From: sashiko-bot@kernel.org
To: "Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>
Cc: linux-rt-devel@lists.linux.dev, tj@kernel.org,
hannes@cmpxchg.org, mkoutny@suse.com,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 04/12] sched/deadline: Do not lose a throttled task switched out and back
Date: Wed, 04 Nov 2026 15:42:42 +0000 [thread overview]
Message-ID: <sashiko-outbox-197527@kernel.org> (raw)
In-Reply-To: <1b0485061f99455deaca614016de741f2091c4a8.1793804635.git.mathieu.desnoyers@efficios.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] sched/deadline: incomplete replenishment when clearing dl_throttled
- [Medium] sched/deadline: stale dl_yielded left set by dl_task_timer()
--
commit b274aa4dbc0a2822908373f43a14a8b8436d20eb
Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
sched/deadline: Do not lose a throttled task switched out and back
This commit clears dl_se->dl_throttled in dl_task_timer() when a throttled
SCHED_DEADLINE task has been switched to another scheduling policy before
its replenishment timer fires, so that switching back to SCHED_DEADLINE
before the 0-lag time does not leave the task permanently throttled.
> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> index 30a52e42c26d8..d474fbfd9be6d 100644
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c
> @@ -1232,10 +1232,17 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
>
> /*
> * The task might have changed its scheduling policy to something
> - * different than SCHED_DEADLINE (through switched_from_dl()).
> + * different than SCHED_DEADLINE (through switched_from_dl()). It
> + * keeps its parameters until its 0-lag time and may come back to
> + * SCHED_DEADLINE before then, switched_to_dl() cancelling the
> + * inactive timer: it must not come back throttled, since this was
> + * its replenishment. Its deadline has passed: the enqueue starts a
> + * new period.
> */
> - if (!dl_task(p))
> + if (!dl_task(p)) {
> + dl_se->dl_throttled = 0;
> goto unlock;
> + }
[Severity: Medium]
Could clearing only dl_se->dl_throttled here without calling
replenish_dl_entity(dl_se) forgive negative runtime overruns and leave
dl_se->deadline stale when the task switches back to SCHED_DEADLINE before
its 0-lag time?
The window between the replenishment timer and the inactive timer exists
specifically when a task has overrun its runtime (dl_se->runtime < 0),
making the 0-lag time later than dl_next_period(dl_se). Normal replenishment
in replenish_dl_entity() deducts that overrun from subsequent periods:
kernel/sched/deadline.c:replenish_dl_entity() {
...
while (dl_se->runtime <= 0) {
dl_se->deadline += pi_of(dl_se)->dl_period;
dl_se->runtime += pi_of(dl_se)->dl_runtime;
}
...
}
By only clearing dl_se->dl_throttled and leaving dl_se->deadline in the past
and dl_se->runtime negative, a task returning to SCHED_DEADLINE before its
0-lag time enters enqueue_dl_entity(), where setup_new_dl_entity() (on
ENQUEUE_MOVE) or update_dl_entity() (on ENQUEUE_WAKEUP) calls
replenish_dl_new_period(dl_se, rq):
kernel/sched/deadline.c:enqueue_dl_entity() {
...
} else if ((flags & ENQUEUE_MOVE) &&
!is_dl_boosted(dl_se) &&
dl_time_before(dl_se->deadline, rq_clock(rq_of_dl_se(dl_se)))) {
setup_new_dl_entity(dl_se);
}
...
}
replenish_dl_new_period() unconditionally resets dl_se->runtime to the full
pi_of(dl_se)->dl_runtime rather than deducting the prior negative runtime
overrun, allowing the task to bypass bandwidth enforcement by switching
policies across its replenishment point.
In addition, in enqueue_dl_entity(), dl_check_constrained_dl() runs before
the ENQUEUE_MOVE branch:
kernel/sched/deadline.c:enqueue_dl_entity() {
...
if (!dl_se->dl_throttled && !dl_is_implicit(dl_se))
dl_check_constrained_dl(dl_se);
...
}
If the task returns with constrained-deadline parameters (for example, with
a larger dl_period passed to sched_setattr() so that dl_se->deadline <
rq_clock(rq) < dl_next_period(dl_se)), dl_check_constrained_dl() sees the
un-advanced dl_se->deadline and re-throttles the task before
setup_new_dl_entity() is reached. And if the task migrated to another CPU
while in SCHED_OTHER whose rq_clock(rq) has not yet strictly passed
dl_se->deadline when it switches back, dl_time_before(dl_se->deadline,
rq_clock(rq)) evaluates to false and the task is enqueued onto dl_rq with
dl_se->runtime <= 0.
[Severity: Medium]
What happens if the task had also called sched_yield() in the period where
it was throttled, leaving dl_se->dl_yielded set to 1 when dl_task_timer()
fires?
In yield_task_dl(), rq->donor->dl.dl_yielded = 1 is set before calling
update_curr_dl(rq) -> update_curr_dl_se():
kernel/sched/deadline.c:yield_task_dl() {
...
rq->donor->dl.dl_yielded = 1;
update_rq_clock(rq);
update_curr_dl(rq);
...
}
If the elapsed execution time in that slice also pushes dl_se->runtime < 0,
update_curr_dl_se() throttles the task with both dl_se->dl_throttled == 1
and dl_se->dl_yielded == 1, and arms the inactive timer for a 0-lag time
later than the deadline when the task switches out of SCHED_DEADLINE.
Unlike replenish_dl_entity() and __dl_clear_params(), which clear both
dl_se->dl_yielded and dl_se->dl_throttled:
kernel/sched/deadline.c:replenish_dl_entity() {
...
if (dl_se->dl_yielded)
dl_se->dl_yielded = 0;
if (dl_se->dl_throttled)
dl_se->dl_throttled = 0;
...
}
neither the !dl_task(p) path in dl_task_timer() nor replenish_dl_new_period()
clears dl_se->dl_yielded. When the task switches back to SCHED_DEADLINE
before its 0-lag time, wouldn't it be enqueued with a stale
dl_se->dl_yielded == 1 and immediately get throttled again for an entire
new period on the next call to update_curr_dl_se()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793804635.git.mathieu.desnoyers@efficios.com?part=4
next prev parent reply other threads:[~2026-11-04 15:42 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 15:10 [PATCH 00/12] sched/deadline: bandwidth accounting fixes and selftests Mathieu Desnoyers
2026-11-04 15:10 ` [PATCH 01/12] sched: Reject SCHED_FLAG_KEEP_PARAMS before reserving deadline bandwidth Mathieu Desnoyers
2026-11-04 15:30 ` sashiko-bot
2026-11-04 15:52 ` Mathieu Desnoyers
2026-11-04 15:10 ` [PATCH 02/12] sched/deadline: Do not divide by zero active CPUs of a root domain Mathieu Desnoyers
2026-11-04 15:10 ` [PATCH 03/12] sched/deadline: Do not BUG() on a deadline task with no active CPU allowed Mathieu Desnoyers
2026-11-04 15:39 ` sashiko-bot
2026-11-04 15:10 ` [PATCH 04/12] sched/deadline: Do not lose a throttled task switched out and back Mathieu Desnoyers
2026-11-04 15:42 ` sashiko-bot [this message]
2026-11-04 15:10 ` [PATCH 05/12] sched/deadline: Do not release a departing sleeper's bandwidth twice Mathieu Desnoyers
2026-11-04 15:33 ` sashiko-bot
2026-11-04 15:10 ` [PATCH 06/12] selftests/sched: Add a test of SCHED_DEADLINE policy round trips Mathieu Desnoyers
2026-11-04 15:10 ` [PATCH 07/12] sched/deadline: Keep departing bandwidth across a root domain rebuild Mathieu Desnoyers
2026-11-04 15:47 ` sashiko-bot
2026-11-04 15:10 ` [PATCH 08/12] selftests/sched: Test SCHED_DEADLINE " Mathieu Desnoyers
2026-11-04 15:10 ` [PATCH 09/12] sched/deadline: Do not take a waking task's bandwidth off a runqueue it left Mathieu Desnoyers
2026-11-04 15:45 ` sashiko-bot
2026-11-04 15:10 ` [PATCH 10/12] sched/debug: Show the deadline bandwidth of each runqueue Mathieu Desnoyers
2026-11-04 15:10 ` [PATCH 11/12] sched/deadline: Rebuild the root domains' accounting without cpusets too Mathieu Desnoyers
2026-11-04 15:45 ` sashiko-bot
2026-11-04 15:10 ` [PATCH 12/12] selftests/sched: Add a test of SCHED_DEADLINE bandwidth accounting Mathieu Desnoyers
2026-11-04 15:52 ` sashiko-bot
2026-11-04 20:24 ` [PATCH 00/12] sched/deadline: bandwidth accounting fixes and selftests Mathieu Desnoyers
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=sashiko-outbox-197527@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=mathieu.desnoyers@efficios.com \
--cc=mkoutny@suse.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tj@kernel.org \
/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
all inboxes | Powered by JetHome®