From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: juri.lelli@redhat.com, peterz@infradead.org, mingo@redhat.com,
vincent.guittot@linaro.org
Cc: linux-kernel@vger.kernel.org,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
tglx@kernel.org, will@kernel.org, boqun@kernel.org,
dietmar.eggemann@arm.com, rostedt@goodmis.org,
bsegall@google.com, mgorman@suse.de, vschneid@redhat.com,
kprateek.nayak@amd.com, luca.abeni@santannapisa.it,
mathieu.poirier@linaro.org, longman@redhat.com,
ridong.chen@linux.dev, tj@kernel.org, hannes@cmpxchg.org,
mkoutny@suse.com, shuah@kernel.org, bigeasy@linutronix.de,
clrkwllms@kernel.org, parri.andrea@gmail.com,
m.szyprowski@samsung.com, kayracizmeci@gmail.com,
weihengqiuu@gmail.com, cgroups@vger.kernel.org,
linux-kselftest@vger.kernel.org, linux-rt-devel@lists.linux.dev
Subject: [PATCH v4 00/26] sched/deadline: bandwidth accounting fixes and selftests
Date: Fri, 6 Nov 2026 20:44:25 -0500 [thread overview]
Message-ID: <20261107014451.1487825-1-mathieu.desnoyers@efficios.com> (raw)
Hi Ingo, Juri,
This series fixes twenty-two bugs of SCHED_DEADLINE, most of them in its
bandwidth accounting, then adds each runqueue's deadline bandwidth to
sched_debug and three selftests: twenty-six patches on tip sched/urgent,
the fixes first, as you asked, so that stable can take 1 to 22. Three of
the bugs take the kernel down (patches 5, 8 and 20), two leave
cpuset_mutex unusable (1 and 6), and most of the others leave a root
domain's total_bw or a runqueue's this_bw wrong: the root domain then
admits deadline tasks beyond its capacity, or refuses every one.
It applies on top of "locking/rtmutex: priority inheritance fixes and
tests", posted for Peter and Thomas: patch 8 rests on its patch 3. Patch
1 is Andrea Parri's, reviewed by Waiman, Kayra and Juri, carried here
because patches 6 and 14 build on it, now with my Signed-off-by; take it
from whichever route you prefer.
Your four fixes, Juri, which Ingo dropped from sched/urgent after the
first crashed Marek Szyprowski's hotplug test, are patches 16 (1/4,
without the task's mask, which has no active CPU during hotplug), 10
(2/4, without its double release, and without your Signed-off-by, which
is yours to add back), 2 (3/4) and 11 (4/4, extended). Marek found v2
fixed on the board that crashed.
The fixes, by patch number
==========================
1 a retry in __sched_setscheduler() unlocks a cpuset_mutex it no
longer holds (Andrea Parri);
2 SCHED_FLAG_KEEP_PARAMS carries out half of a policy or class change,
and leaks the bandwidth of a boosted task;
3 SCHED_FLAG_KEEP_PARAMS admits stale parameters, read without a lock;
4 a task boosted by a deadline waiter cannot leave for another policy
(EBUSY);
5 a debugfs write to a fair server divides by zero active CPUs while
its CPU goes offline or comes online;
6 sysrq-n takes cpuset_mutex under tasklist_lock and never releases
it;
7 a throttled task switched out and back before its 0-lag time never
runs again;
8 the owner boosted by a deadline waiter that leaves the class loops
forever in replenish_dl_entity(), under the runqueue lock;
9 a task back in the class runs on the deadline and runtime of the
period it left, or of the donor that boosted it;
10 a task that leaves the class asleep keeps its bandwidth in total_bw
for good;
11 SCHED_DEADLINE on a zombie reserves bandwidth nothing releases, and
a zombie switched out of the class is taken off its cpuset's count
twice;
12 a rebuild of the accounting forgets the bandwidth of tasks that left
the class, or died, before their 0-lag time, which is then released
twice;
13 a parameter change while a wakeup is in flight underflows the
this_bw of a runqueue that never held the task's bandwidth;
14 without cpusets, the first hotplug drops the bandwidth of every
deadline task; with them, a drifting count has every rebuild drop a
cpuset's tasks;
15 a rebuild counts the bandwidth of a task at its last schedule, which
nothing releases;
16 admission, moves and rebuilds disagree on the root domain that
counts a task's bandwidth, and take it from one that never had it;
17 a cpuset move takes bandwidth off a root domain with no room made
for it: total_bw of a partition reaches 2^64 - 262144;
18 a rebuild of the sched domains between cpuset_can_attach() and
cpuset_attach() drops the attach's reservation;
19 an attach leaves in the destination's total_bw the reservation of a
task that left the class, or died, before it;
20 a rebuild counts a task on the first active CPU of its cpuset: an
isolated one, none at all (BUG()), or not where
dl_task_offline_migration() moved it;
21 a replenishment timer left armed across a class round trip fires at
the period of the reservation the task left;
22 sched_setattr(SCHED_DEADLINE) on a boosted task leaves its
runqueue's this_bw without the task's bandwidth, and a sugov
kthread's own reservation is never admitted.
Patch 23 shows patch 13's bug from userspace; patches 24 to 26 add 55
cases in tools/testing/selftests/sched/deadline, as Juri suggested.
Patches 16 to 20 go together: 16 records the root domain that counts a
task's bandwidth, and 17 to 20 fix the attach and rebuild paths that the
record exposes. Patch 22 completes patch 13.
Patch 8 touches the rt_mutex code, Peter and Thomas: it records a
deadline waiter's reservation in its rt_mutex node, which grows struct
rt_mutex_waiter by 48 bytes, and takes a deadline boost from there; the
other classes keep the waiter's own priority, as since acd58620e415
("sched/rtmutex: Refactor rt_mutex_setprio()").
Testing
=======
The 55 cases pass every time with no kernel warning in 16 QEMU guests,
lockdep on: 8 of 8 vCPUs, and 2 each of 4 vCPUs, PREEMPT_RT, proxy
execution off and no CONFIG_CPUSETS. v7.4-rc1 fails 19 of them, which
patches 24 to 26 list, and three hotplug cases without cpusets. Kernels
stopped at single patches confirm the claims of patches 10, 12, 18 and
19. Patch 8 has no selftest: a debug delay or a stress test locks
v7.4-rc1 up, and the series runs the stress test for 600 seconds; the
locking API, ww_mutex, locktorture and futex selftests pass, with and
without PREEMPT_RT.
How this was developed
======================
These patches, their messages and the tests were written by an LLM
coding assistant under my direction and review. I am at home with the
concepts behind SCHED_DEADLINE, but not with its implementation, so I am
asking those who know this code for a careful reading of the fixes: a
reproducer that stops failing says that the symptom goes away, not that
the fix is the one you would have written. The bugs came from flaky
cgroup selftests of a feature I am developing, from reviewing Juri's
four fixes, from building deadline_bw_test, from reading the code, and
from the Sashiko AI reviews of v1 to v3, each finding checked against
the code first; the patches changed since v3 also went through a local
Sashiko run before posting.
Changes since v3
================
- rebased on tip sched/urgent, which took Nickolai Zeldovich's this_bw
fix for a dying task; patch 12 keeps its dl_task test;
- new patches 4 (a boosted task may change its policy) and 8 (a
deadline boost from the waiter's rt_mutex node);
- 1: my Signed-off-by; 5: rq->online instead of cpu_active(); 6:
cpuset_mutex decided again under the runqueue lock; 9: the deboost of
a task with no parameters resets the donor's deadline and runtime;
- 10: an inactive timer where the 0-lag time is ahead, and the
parameters cleared with the bandwidth; 14: the rebuild walks the task
list with cpusets too, without the per-cpuset count, and leaves out
tasks with no bandwidth;
- 16: special and boosted tasks with no bandwidth of their own are not
moved; 18: waits in cpuset_full_lock() too; 20: the task's own mask
first, and dl_task_offline_migration() counts a task a rebuild left
out; 22: checks that the bandwidth is counted before a no-op, and
leaves the runqueue alone when it is kept;
- deadline_bw_test: boosted_owner_policy, deboost_resets_period and
deboost_released_resets_period added, three cases fixed to reach the
state they are named for, CPUs from the online set, error paths that
join their threads;
- deadline_switch_test: its children die with the test
(PR_SET_PDEATHSIG);
- shorter commit messages.
Not changed: a departed task boosted into the class is counted
conservatively across a rebuild, never twice, and the EPERM of a
sleeping task moved to another partition is the baseline's affinity
check.
Based on tip sched/urgent, 006991aa8997, with "locking/rtmutex: priority
inheritance fixes and tests" applied first:
https://lore.kernel.org/lkml/20261106235931.1478800-1-mathieu.desnoyers@efficios.com
v3: https://lore.kernel.org/all/20261105193359.1450487-1-mathieu.desnoyers@efficios.com/
Andrea Parri (1):
sched: Fix cpuset_mutex double unlock in __sched_setscheduler()
Juri Lelli (1):
sched/deadline: Reject SCHED_DEADLINE on exited tasks
Mathieu Desnoyers (24):
sched: Refuse SCHED_FLAG_KEEP_PARAMS that would change the policy or
the class
sched/deadline: Do not admit bandwidth for parameters that are kept
sched: Let a task boosted by a deadline waiter change its policy
sched/deadline: Do not divide by zero active CPUs of a root domain
sched: Take cpuset_mutex for a deadline policy change only with pi
sched/deadline: Do not lose a throttled task switched out and back
sched/deadline: Take a deadline boost from the waiter's rt_mutex node
sched/deadline: Reset the deadline and the runtime with the parameters
sched/deadline: Release the bandwidth of a task that leaves the class
asleep
sched/deadline: Keep departing bandwidth across a root domain rebuild
sched/deadline: Do not take a waking task's bandwidth off a runqueue
it left
sched/deadline: Rebuild the root domains' accounting from the task
list
sched/deadline: Leave a dying task out of a rebuild of the accounting
sched/deadline: Record the root domain holding a task's bandwidth
sched/deadline: Move a task's bandwidth only where room was made
cgroup/cpuset: Wait for an attach before rebuilding the sched domains
cgroup/cpuset: Give back the bandwidth an attach did not move
sched/deadline: Credit a rebuild to the CPU recorded with the task's
bandwidth
sched/deadline: Cancel the replenishment timer with the parameters
sched/deadline: Count the bandwidth a boosted task is given
sched/debug: Show the deadline bandwidth of each runqueue
selftests/sched: Add a test of SCHED_DEADLINE policy round trips
selftests/sched: Test SCHED_DEADLINE bandwidth across a root domain
rebuild
selftests/sched: Add a test of SCHED_DEADLINE bandwidth accounting
include/linux/cpuset.h | 9 -
include/linux/sched.h | 47 +-
include/linux/sched/deadline.h | 38 +-
include/linux/sched/rt.h | 11 -
kernel/cgroup/cgroup.c | 3 -
kernel/cgroup/cpuset-internal.h | 8 +-
kernel/cgroup/cpuset.c | 126 +-
kernel/locking/rtmutex.c | 41 +-
kernel/locking/rtmutex_api.c | 2 +-
kernel/locking/rtmutex_common.h | 5 +
kernel/sched/core.c | 88 +-
kernel/sched/deadline.c | 799 +++-
kernel/sched/debug.c | 11 +-
kernel/sched/sched.h | 23 +-
kernel/sched/syscalls.c | 87 +-
kernel/sched/topology.c | 9 +
tools/testing/selftests/Makefile | 1 +
.../selftests/sched/deadline/.gitignore | 3 +
.../testing/selftests/sched/deadline/Makefile | 8 +
tools/testing/selftests/sched/deadline/config | 4 +
.../sched/deadline/deadline_bw_test.c | 3902 +++++++++++++++++
.../sched/deadline/deadline_rebuild_test.c | 462 ++
.../sched/deadline/deadline_switch_test.c | 440 ++
.../testing/selftests/sched/deadline/settings | 1 +
24 files changed, 5847 insertions(+), 281 deletions(-)
create mode 100644 tools/testing/selftests/sched/deadline/.gitignore
create mode 100644 tools/testing/selftests/sched/deadline/Makefile
create mode 100644 tools/testing/selftests/sched/deadline/config
create mode 100644 tools/testing/selftests/sched/deadline/deadline_bw_test.c
create mode 100644 tools/testing/selftests/sched/deadline/deadline_rebuild_test.c
create mode 100644 tools/testing/selftests/sched/deadline/deadline_switch_test.c
create mode 100644 tools/testing/selftests/sched/deadline/settings
base-commit: 006991aa89974378ee579416dba87adc22cd60fd
prerequisite-patch-id: 382feddeb27d226d8711d23036c8ae0c8629c680
prerequisite-patch-id: 72e83c74aa52fcd32afb2909b071f40c82b0ef10
prerequisite-patch-id: cfd50da1cef9606aafc687658a1ac79f74969703
prerequisite-patch-id: 2e79dc888982d901d6e8b3784790ef71037482a9
prerequisite-patch-id: f7338b3af8aeb24a47d19dff76d7e3180120b9aa
--
2.47.3
next reply other threads:[~2026-11-07 1:44 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 1:44 Mathieu Desnoyers [this message]
2026-11-07 1:44 ` [PATCH v4 01/26] sched: Fix cpuset_mutex double unlock in __sched_setscheduler() Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 02/26] sched: Refuse SCHED_FLAG_KEEP_PARAMS that would change the policy or the class Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 03/26] sched/deadline: Do not admit bandwidth for parameters that are kept Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 04/26] sched: Let a task boosted by a deadline waiter change its policy Mathieu Desnoyers
2026-11-07 2:13 ` sashiko-bot
2026-11-07 1:44 ` [PATCH v4 05/26] sched/deadline: Do not divide by zero active CPUs of a root domain Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 06/26] sched: Take cpuset_mutex for a deadline policy change only with pi Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 07/26] sched/deadline: Do not lose a throttled task switched out and back Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 08/26] sched/deadline: Take a deadline boost from the waiter's rt_mutex node Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 09/26] sched/deadline: Reset the deadline and the runtime with the parameters Mathieu Desnoyers
2026-11-07 2:18 ` sashiko-bot
2026-11-07 1:44 ` [PATCH v4 10/26] sched/deadline: Release the bandwidth of a task that leaves the class asleep Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 11/26] sched/deadline: Reject SCHED_DEADLINE on exited tasks Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 12/26] sched/deadline: Keep departing bandwidth across a root domain rebuild Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 13/26] sched/deadline: Do not take a waking task's bandwidth off a runqueue it left Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 14/26] sched/deadline: Rebuild the root domains' accounting from the task list Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 15/26] sched/deadline: Leave a dying task out of a rebuild of the accounting Mathieu Desnoyers
2026-11-07 2:10 ` sashiko-bot
2026-11-07 1:44 ` [PATCH v4 16/26] sched/deadline: Record the root domain holding a task's bandwidth Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 17/26] sched/deadline: Move a task's bandwidth only where room was made Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 18/26] cgroup/cpuset: Wait for an attach before rebuilding the sched domains Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 19/26] cgroup/cpuset: Give back the bandwidth an attach did not move Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 20/26] sched/deadline: Credit a rebuild to the CPU recorded with the task's bandwidth Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 21/26] sched/deadline: Cancel the replenishment timer with the parameters Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 22/26] sched/deadline: Count the bandwidth a boosted task is given Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 23/26] sched/debug: Show the deadline bandwidth of each runqueue Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 24/26] selftests/sched: Add a test of SCHED_DEADLINE policy round trips Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 25/26] selftests/sched: Test SCHED_DEADLINE bandwidth across a root domain rebuild Mathieu Desnoyers
2026-11-07 1:44 ` [PATCH v4 26/26] selftests/sched: Add a test of SCHED_DEADLINE bandwidth accounting 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=20261107014451.1487825-1-mathieu.desnoyers@efficios.com \
--to=mathieu.desnoyers@efficios.com \
--cc=bigeasy@linutronix.de \
--cc=boqun@kernel.org \
--cc=bsegall@google.com \
--cc=cgroups@vger.kernel.org \
--cc=clrkwllms@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=hannes@cmpxchg.org \
--cc=juri.lelli@redhat.com \
--cc=kayracizmeci@gmail.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=longman@redhat.com \
--cc=luca.abeni@santannapisa.it \
--cc=m.szyprowski@samsung.com \
--cc=mathieu.poirier@linaro.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=mkoutny@suse.com \
--cc=parri.andrea@gmail.com \
--cc=peterz@infradead.org \
--cc=ridong.chen@linux.dev \
--cc=rostedt@goodmis.org \
--cc=shuah@kernel.org \
--cc=tglx@kernel.org \
--cc=tj@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
--cc=weihengqiuu@gmail.com \
--cc=will@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®