From: sashiko-bot@kernel.org
To: "Pasha Tatashin" <pasha.tatashin@soleen.com>,
kees@kernel.org, rppt@kernel.org, juri.lelli@redhat.com,
nik.borisov@suse.com, tglx@kernel.org, vschneid@redhat.com,
kprateek.nayak@amd.com, vincent.guittot@linaro.org, bp@alien8.de,
thorsten.blum@linux.dev, tony.luck@intel.com, david@kernel.org,
mingo@redhat.com, akpm@linux-foundation.org, seanjc@google.com,
ljs@kernel.org, zhangguopeng@kylinos.cn,
dietmar.eggemann@arm.com, mhocko@suse.com,
vinicius.gomes@intel.com, tj@kernel.org, vbabka@kernel.org,
peterz@infradead.org, surenb@google.com, hpa@zytor.com,
x86@kernel.org, dmatlack@google.com, tim.c.chen@linux.intel.com,
kexec@lists.infradead.org, pratyush@kernel.org,
dave.hansen@linux.intel.com, rostedt@goodmis.org,
gmonaco@redhat.com, jgross@suse.com, mgorman@suse.de,
graf@amazon.com, liam@infradead.org, ridong.chen@linux.dev,
longman@redhat.com, bsegall@google.com
Cc: hannes@cmpxchg.org, mkoutny@suse.com
Subject: Re: [PATCH v1 6/8] sched/deadline, topology: Avoid O(N^2) dl_server bandwidth walks during root_domain rebuilds
Date: Thu, 15 Oct 2026 15:57:27 +0000 [thread overview]
Message-ID: <sashiko-outbox-173118@kernel.org> (raw)
In-Reply-To: <20261015153331.1872641-7-pasha.tatashin@soleen.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] sched/deadline: Concurrent sched_setattr() during dl_rebuild_rd_accounting() corrupts bandwidth (!CONFIG_CPUSETS)
- [Medium] sched/deadline: root domain bandwidth leak for DEAD tasks on offline CPUs
- [Medium] sched/deadline: lockless u64 write to extra_bw causes data race and torn reads
--
commit 2fcbfb40fdf44ef2a7ddc6709657336b0c7fb178
Author: Pasha Tatashin <pasha.tatashin@soleen.com>
sched/deadline, topology: Avoid O(N^2) dl_server bandwidth walks during root_domain rebuilds
This commit reduces the O(N^2) complexity of dl_server bandwidth walks during
root_domain rebuilds by accumulating the total bandwidth in a single pass. It
also introduces a !CONFIG_CPUSETS implementation of dl_rebuild_rd_accounting()
to fix an issue where SCHED_DEADLINE task bandwidth was not accounted for on
rebuilds.
> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> index 857dbe3519a86..01f2f24e3b814 100644
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c
[ ... ]
> @@ -3480,26 +3466,32 @@ static u64 dl_server_read_bw(int cpu)
> return dl_bw;
> }
>
> -void dl_clear_root_domain(struct root_domain *rd)
> +static void dl_clear_root_domain(struct root_domain *rd)
> {
> - int i;
> + u64 total_bw = 0;
> + s64 extra_bw = 0;
> + int i, cpus;
>
> guard(raw_spinlock_irqsave)(&rd->dl_bw.lock);
>
[ ... ]
> + rd->dl_bw.total_bw = total_bw;
> + for_each_cpu(i, rd->span) {
> + struct rq *rq = cpu_rq(i);
> +
> + rq->dl.extra_bw = rq->dl.max_bw;
> + if (cpu_active(i))
> + rq->dl.extra_bw += extra_bw;
[Severity: Medium]
Can this lockless u64 write to extra_bw cause a data race and torn reads with
grub_reclaim()?
This updates rq->dl.extra_bw remotely holding only rd->dl_bw.lock. Concurrently,
grub_reclaim() reads rq->dl.extra_bw while holding only the local rq->lock.
Because extra_bw is a u64 and can be a negative delta, 32-bit architectures
process the write as two 32-bit stores. A torn read by grub_reclaim() could
observe mismatched upper and lower halves, producing an incorrect bandwidth
value that miscalculates DL task runtime.
Additionally, splitting the update into two distinct non-atomic assignments
widens the race window.
> + }
> }
>
> void dl_clear_root_domain_cpu(int cpu)
[ ... ]
> @@ -3507,6 +3499,33 @@ void dl_clear_root_domain_cpu(int cpu)
> dl_clear_root_domain(cpu_rq(cpu)->rd);
> }
>
> +#ifndef CONFIG_CPUSETS
> +void dl_rebuild_rd_accounting(void)
> +{
> + struct task_struct *g, *p;
> + u64 cookie = ++dl_cookie;
> + int cpu;
> +
> + lockdep_assert_cpus_held();
> + lockdep_assert_held(&sched_domains_mutex);
> +
> + rcu_read_lock();
> + for_each_possible_cpu(cpu) {
> + if (dl_bw_visited(cpu, cookie))
> + continue;
> +
> + dl_clear_root_domain_cpu(cpu);
> + }
> + for_each_process_thread(g, p) {
> + /* Racy pre-check; dl_add_task_root_domain() rechecks under pi_lock. */
> + if (!dl_prio(READ_ONCE(p->prio)))
> + continue;
> + dl_add_task_root_domain(p);
[Severity: High]
Does this allow a race with concurrent __sched_setscheduler()?
In a kernel without CONFIG_CPUSETS, cpuset_lock() is an empty no-op stub,
leaving __sched_setscheduler() completely unsynchronized against this loop.
If sched_setattr() transitions a task to SCHED_DEADLINE concurrently,
__sched_setscheduler() calls sched_dl_overflow() which acquires dl_b->lock
and adds the task's bandwidth. Then this iteration loop could observe the new
priority, call dl_add_task_root_domain(), and add the bandwidth a second time,
corrupting rd->dl_bw.total_bw.
Similarly, a task transitioning from SCHED_DEADLINE to SCHED_OTHER could result
in a bandwidth underflow because the rebuild clears the bandwidth, skips the
task, and later inactive_task_timer() subtracts the bandwidth.
[Severity: Medium]
Does this leak SCHED_DEADLINE bandwidth in the active root domain for DEAD tasks
on offline CPUs?
This loop blindly iterates over all tasks, including TASK_DEAD zombies, without
checking the task state. If a SCHED_DEADLINE task exits and enters TASK_DEAD
state, its bandwidth is preserved until its 0-lag inactive timer fires.
If its original CPU is hotplugged offline before the timer fires, CPU hotplug
triggers this domain rebuild. Because the task's original CPU is offline,
dl_add_task_root_domain() picks a new active CPU and adds the task's bandwidth
to the new active root domain.
When the 0-lag timer eventually fires, inactive_task_timer() subtracts the
bandwidth from task_cpu(p)'s root domain (the def_root_domain, since it was
never migrated), permanently leaking the bandwidth in the active root domain.
> + }
> + rcu_read_unlock();
> +}
> +#endif
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261015153331.1872641-1-pasha.tatashin@soleen.com?part=6
next prev parent reply other threads:[~2026-10-15 15:57 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 15:33 [PATCH v1 0/8] x86, sched, mm: Speed up CPU hotplug on large systems Pasha Tatashin
2026-10-15 15:33 ` [PATCH v1 1/8] x86/realmode: Remove unnecessary WBINVD from AP startup trampoline Pasha Tatashin
2026-10-15 15:41 ` sashiko-bot
2026-10-15 15:33 ` [PATCH v1 2/8] x86/smp: Remove unnecessary WBINVD from mwait_play_dead() Pasha Tatashin
2026-10-15 15:44 ` sashiko-bot
2026-10-15 16:26 ` Pasha Tatashin
2026-10-15 15:33 ` [PATCH v1 3/8] x86/mce/intel: Bound cmci_rediscover() to a single topology peer Pasha Tatashin
2026-10-15 15:51 ` sashiko-bot
2026-10-15 15:33 ` [PATCH v1 4/8] x86/cacheinfo, mtrr: Skip stop_machine rendezvous in cache_ap_online() when MTRRs match Pasha Tatashin
2026-10-15 15:45 ` sashiko-bot
2026-10-15 15:33 ` [PATCH v1 5/8] sched/topology: Avoid redundant O(N^3) group capacity walks and unused allocations in build_sched_domains() Pasha Tatashin
2026-10-15 15:43 ` sashiko-bot
2026-10-15 15:33 ` [PATCH v1 6/8] sched/deadline, topology: Avoid O(N^2) dl_server bandwidth walks during root_domain rebuilds Pasha Tatashin
2026-10-15 15:57 ` sashiko-bot [this message]
2026-10-15 20:43 ` Pasha Tatashin
2026-10-15 15:33 ` [PATCH v1 7/8] sched/topology: Avoid redundant percpu allocations and bitmap walks in build_sched_domains() Pasha Tatashin
2026-10-15 15:51 ` sashiko-bot
2026-10-15 23:17 ` Tim Chen
2026-10-15 15:33 ` [PATCH v1 8/8] mm/vmstat: Avoid redundant per-CPU stat_threshold writes in refresh_zone_stat_thresholds() Pasha Tatashin
2026-10-15 15:49 ` sashiko-bot
2026-10-15 21:33 ` [PATCH v1 0/8] x86, sched, mm: Speed up CPU hotplug on large systems Luck, Tony
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-173118@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=bp@alien8.de \
--cc=bsegall@google.com \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=dmatlack@google.com \
--cc=gmonaco@redhat.com \
--cc=graf@amazon.com \
--cc=hannes@cmpxchg.org \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=juri.lelli@redhat.com \
--cc=kees@kernel.org \
--cc=kexec@lists.infradead.org \
--cc=kprateek.nayak@amd.com \
--cc=liam@infradead.org \
--cc=ljs@kernel.org \
--cc=longman@redhat.com \
--cc=mgorman@suse.de \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=mkoutny@suse.com \
--cc=nik.borisov@suse.com \
--cc=pasha.tatashin@soleen.com \
--cc=peterz@infradead.org \
--cc=pratyush@kernel.org \
--cc=ridong.chen@linux.dev \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=seanjc@google.com \
--cc=surenb@google.com \
--cc=tglx@kernel.org \
--cc=thorsten.blum@linux.dev \
--cc=tim.c.chen@linux.intel.com \
--cc=tj@kernel.org \
--cc=tony.luck@intel.com \
--cc=vbabka@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vinicius.gomes@intel.com \
--cc=vschneid@redhat.com \
--cc=x86@kernel.org \
--cc=zhangguopeng@kylinos.cn \
/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.