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 03/12] sched/deadline: Do not BUG() on a deadline task with no active CPU allowed
Date: Wed, 04 Nov 2026 15:39:34 +0000 [thread overview]
Message-ID: <sashiko-outbox-197525@kernel.org> (raw)
In-Reply-To: <9cf4959749b84933fa506de5fc43b2dc0e02cd05.1793804635.git.mathieu.desnoyers@efficios.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] sched/deadline: stale root domain in dl_task_root_domain_cpu() fallback
--
commit 1ac76c29bedf1013e2c606590748a52f51b1170b
Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
sched/deadline: Do not BUG() on a deadline task with no active CPU allowed
This commit replaces the BUG_ON(cpu >= nr_cpu_ids) in
dl_task_root_domain_cpu() with a fallback to task_cpu(p) when a deadline
task's cpus_mask contains no active CPUs.
> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> index dadda1a528ec6..30a52e42c26d8 100644
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c
> @@ -3338,13 +3338,19 @@ static void task_woken_dl(struct rq *rq, struct task_struct *p)
> * current cpus_mask (not yet updated to the new mask) to find the
> * actual root domain. Use cpus_mask rather than cpus_ptr, which
> * may be temporarily narrowed by migrate_disable().
> + *
> + * The mask has no active CPU left when the CPUs it allows went offline,
> + * which the affinity of a deadline task allows with admission control
> + * off, and that of a task boosted into the deadline class by priority
> + * inheritance always: fall back to the CPU the task last ran on.
> */
> static unsigned int dl_task_root_domain_cpu(struct task_struct *p)
> {
> unsigned int cpu;
>
> cpu = cpumask_first_and(&p->cpus_mask, cpu_active_mask);
> - BUG_ON(cpu >= nr_cpu_ids);
> + if (cpu >= nr_cpu_ids)
> + cpu = task_cpu(p);
> return cpu;
> }
[Severity: High]
When a deadline task's cpus_mask has no active CPUs left, can falling back
to task_cpu(p) in dl_task_root_domain_cpu() return an offline or stale CPU
whose root domain no longer holds p->dl.dl_bw?
For example, with admission control disabled (sched_rt_runtime_us == -1),
suppose a SCHED_DEADLINE task p in top_cpuset is pinned via
sched_setaffinity() to CPU 1 (so p->cpus_mask is {1}), runs on CPU 1
(task_cpu(p) == 1), and blocks.
When CPU 1 goes offline via sched_cpu_deactivate(), cpuset_handle_hotplug()
does not rewrite p->cpus_mask for tasks in top_cpuset, so p->cpus_mask
remains {1} and task_cpu(p) remains 1. During the domain rebuild:
partition_sched_domains_locked()
detach_destroy_domains() -> attaches offline CPU 1 to def_root_domain
build_sched_domains() -> attaches remaining active CPUs to rd_active
dl_rebuild_rd_accounting()
dl_clear_root_domain() -> sets def_root_domain.dl_bw.total_bw = 0
dl_add_task_root_domain(p)
In kernel/sched/deadline.c:dl_add_task_root_domain():
msk = this_cpu_cpumask_var_ptr(local_cpu_mask_dl);
dl_get_task_effective_cpus(p, msk);
cpu = cpumask_first_and(cpu_active_mask, msk);
BUG_ON(cpu >= nr_cpu_ids);
rq = cpu_rq(cpu);
dl_b = &rq->rd->dl_bw;
raw_spin_lock(&dl_b->lock);
__dl_add(dl_b, p->dl.dl_bw, cpumask_weight(rq->rd->span));
dl_get_task_effective_cpus() queries cpuset_cpus_allowed_locked(), so p's
bandwidth is accounted into rd_active->dl_bw.total_bw, whereas
cpu_rq(task_cpu(p))->rd is def_root_domain. (Similarly, if a sleeping
deadline task last ran on CPU A in partition A, was moved to a 1-CPU cpuset
on CPU B without waking up, and CPU B goes offline, task_cpu(p) still
points to CPU A in partition A.)
Because dl_task_root_domain_cpu(p) returns task_cpu(p) (CPU 1) while
p->cpus_mask has no active CPUs:
1. In switched_from_dl(), if p changes policy away from SCHED_DEADLINE
while sleeping, __dl_sub() subtracts p->dl.dl_bw from
def_root_domain.dl_bw.total_bw (underflowing it from 0) instead of
rd_active->dl_bw.total_bw, leaking p->dl.dl_bw in rd_active.
2. In dl_task_needs_bw_move() and set_cpus_allowed_dl():
cpu = dl_task_root_domain_cpu(p);
return !cpumask_intersects(cpu_rq(cpu)->rd->span, new_mask);
cpu_rq(1)->rd->span is def_root_domain.span, which contains only
offline CPUs and does not intersect any new_mask of active CPUs.
Updating p's affinity to active CPUs in rd_active via
sched_setaffinity() or cpuset_cpus_allowed_fallback() causes
dl_task_needs_bw_move() to return true and set_cpus_allowed_dl() to
subtract p->dl.dl_bw from def_root_domain.dl_bw.total_bw. Moving p via
cpuset_can_attach() and cpuset_attach_task() to a child cpuset in the
same root domain rd_active causes cpuset_reserve_dl_bw() to add
p->dl.dl_bw a second time to rd_active->dl_bw.total_bw while
set_cpus_allowed_dl() subtracts from def_root_domain; moving p to a
different partition subtracts from def_root_domain instead of rd_active,
leaking p->dl.dl_bw in rd_active.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793804635.git.mathieu.desnoyers@efficios.com?part=3
next prev parent reply other threads:[~2026-11-04 15:39 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 [this message]
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
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-197525@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 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.