mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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 v4 20/26] sched/deadline: Credit a rebuild to the CPU recorded with the task's bandwidth
Date: Sat, 07 Nov 2026 02:48:11 +0000	[thread overview]
Message-ID: <sashiko-outbox-202515@kernel.org> (raw)
In-Reply-To: <20261107014451.1487825-21-mathieu.desnoyers@efficios.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] sched/deadline: stale dl_bw_cpu used by dl_task_rebuild_cpu()
  after fallback migration
- [Medium] sched/deadline: dl_task_rebuild_cpu() disagrees with
  select_fallback_rq() on isolated CPUs
--

commit 95575db84831c783a0bb061a74c9e5615adce1b2
Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>

sched/deadline: Credit a rebuild to the CPU recorded with the task's bandwidth

This commit adds dl_task_rebuild_cpu() so root domain bandwidth rebuilds
credit each deadline task to the CPU recorded with its bandwidth when active
and allowed, and updates dl_task_offline_migration() to add bandwidth even
when a prior rebuild left the task out.

> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> index f169cf35e3136..ed951246e3d2d 100644
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c

[ ... ]

> @@ -3656,6 +3662,47 @@ static void dl_get_task_effective_cpus(struct task_struct *p, struct cpumask *cp
>  	cpuset_cpus_allowed_locked(p, cpus);
>  }
>  
> +/*
> + * A CPU of the root domain that a rebuild of the accounting counts @p's
> + * bandwidth in. The one recorded with it, where it is active and the
> + * cpuset of @p allows it: that of the root domain that admitted the
> + * bandwidth, or that the last move put it in, which the cpuset alone does
> + * not tell where it holds CPUs of two root domains, housekeeping ones
> + * beside the ones isolcpus="domain" leaves to the default root domain. The
> + * record answers as well for a task whose own CPUs went offline, moved to
> + * an active one by dl_task_offline_migration(). Else the first active CPU
> + * the cpuset allows, a housekeeping one where it has any; and nr_cpu_ids
> + * where it allows none, which the isolated CPUs allow, no deadline task
> + * of theirs keeping the last of them online.
> + */
> +static unsigned int dl_task_rebuild_cpu(struct task_struct *p)
> +{
> +	struct cpumask *msk = this_cpu_cpumask_var_ptr(local_cpu_mask_dl);
> +	int recorded = p->dl.dl_bw_cpu;
> +	unsigned int cpu;
> +
> +	/*
> +	 * The task's own CPUs first: a change of cpusets sets the mask of
> +	 * each task before the rebuild it makes, where the housekeeping mask
> +	 * that dl_get_task_effective_cpus() reads lags that change. With
> +	 * none of them active, the CPU recorded is where
> +	 * dl_task_offline_migration() moved the task; else its cpuset says.
> +	 */
> +	cpumask_and(msk, &p->cpus_mask, cpu_active_mask);
> +	if (cpumask_empty(msk)) {
> +		if (recorded >= 0 && cpu_active(recorded))
> +			return recorded;
> +		dl_get_task_effective_cpus(p, msk);
> +		cpumask_and(msk, msk, cpu_active_mask);
> +	}
> +	if (recorded >= 0 && cpumask_test_cpu(recorded, msk))
> +		return recorded;
> +	cpu = cpumask_first_and(msk, housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT));
> +	if (cpu < nr_cpu_ids)
> +		return cpu;
> +	return cpumask_first(msk);
> +}

[Severity: Medium]
Can dl_task_rebuild_cpu() credit a task's bandwidth to a different root
domain than the one select_fallback_rq() places the task on when multiple
CPUs are isolated with isolcpus=domain?

Suppose CPUs 0 and 1 are housekeeping and CPUs 2 and 3 are isolated in
def_root_domain, and a sleeping deadline task is pinned to CPU 2 when CPU 2
goes offline.  Because p->cpus_mask has no active CPU and p->dl.dl_bw_cpu
(2) is inactive, dl_task_rebuild_cpu() falls back to
dl_get_task_effective_cpus(), which sees p->cpus_ptr disjoint from hk_msk
and returns the remaining active isolated CPU 3, so dl_add_task_root_domain()
credits def_root_domain and sets p->dl.dl_bw_cpu = 3.  When the task later
wakes up, select_fallback_rq() -> cpuset_cpus_allowed_fallback() ->
set_cpus_allowed_force() widens p->cpus_mask to all possible CPUs {0..3} and
selects the first active CPU 0 in the housekeeping root domain, while
p->dl.dl_bw_cpu remains 3 (now in p->cpus_mask) so subsequent rebuilds keep
the bandwidth in def_root_domain.

Conversely, if CPUs 0 and 1 are isolated and CPUs 2 and 3 are housekeeping,
and a running task pinned to CPU 0 is migrated by balance_push() ->
select_fallback_rq() when CPU 0 goes offline, select_fallback_rq() widens
p->cpus_mask to {0..3} and moves the task to the first active CPU 1 in
def_root_domain.  When dl_task_rebuild_cpu() then runs with recorded = 0
(inactive) and msk = {1, 2, 3}, cpumask_first_and(msk,
housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT)) picks housekeeping CPU 2 instead
of task_cpu(p) (CPU 1), crediting the housekeeping root domain while the
task runs in def_root_domain.

>  /* From dl_rebuild_rd_accounting(), under the locks it asserts. */
>  void dl_add_task_root_domain(struct task_struct *p)
>  {
> @@ -3663,7 +3710,6 @@ void dl_add_task_root_domain(struct task_struct *p)
>  	struct rq *rq;
>  	struct dl_bw *dl_b;
>  	unsigned int cpu;
> -	struct cpumask *msk;
>  
>  	raw_spin_lock_irqsave(&p->pi_lock, rf.flags);
>  	/*
> @@ -3677,10 +3723,16 @@ void dl_add_task_root_domain(struct task_struct *p)
>  		return;
>  	}
>  
> -	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);
> +	cpu = dl_task_rebuild_cpu(p);
> +	if (cpu >= nr_cpu_ids) {
> +		/*
> +		 * No active CPU to count this task's bandwidth: leave it out
> +		 * of this rebuild, where dl_bw_gen keeps its release out as
> +		 * well, until one has a CPU for it.
> +		 */
> +		raw_spin_unlock_irqrestore(&p->pi_lock, rf.flags);
> +		return;
> +	}

[Severity: Medium]
When a task has no active CPU and is left out of the rebuild here, does
leaving p->dl.dl_bw_cpu untouched cause a later rebuild to credit its
bandwidth back to the old isolated CPU after fallback migration?

If a sleeping task confined to isolated CPU 2 is skipped here when CPU 2
goes offline, p->dl.dl_bw_cpu stays 2.  When the task wakes up while CPU 2
is still offline, try_to_wake_up() -> select_task_rq() ->
select_fallback_rq() calls set_cpus_allowed_force() without
SCA_DL_BW_RESERVED, widening p->cpus_mask to all possible CPUs and moving
the task to a housekeeping CPU without updating p->dl.dl_bw_cpu.  Once CPU 2
is brought back online, dl_task_rebuild_cpu() sees recorded == 2 set in
p->cpus_mask & cpu_active_mask and returns CPU 2, crediting the task's
bandwidth to def_root_domain even though the task was left out of the
previous generation and is now running in the housekeeping root domain.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261107014451.1487825-1-mathieu.desnoyers@efficios.com?part=20

  reply	other threads:[~2026-11-07  2:48 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07  1:44 [PATCH v4 00/26] sched/deadline: bandwidth accounting fixes and selftests Mathieu Desnoyers
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  2:25   ` sashiko-bot
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  2:23   ` sashiko-bot
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  2:22   ` sashiko-bot
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  2:35   ` sashiko-bot
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  2:48   ` sashiko-bot [this message]
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
2026-11-07  2:25   ` sashiko-bot

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-202515@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®