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


             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®