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>,
	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,
	stable@vger.kernel.org
Subject: [PATCH v3 18/24] sched/deadline: Credit a rebuild to the CPU recorded with the task's bandwidth
Date: Thu,  5 Nov 2026 14:33:53 -0500	[thread overview]
Message-ID: <20261105193359.1450487-19-mathieu.desnoyers@efficios.com> (raw)
In-Reply-To: <20261105193359.1450487-1-mathieu.desnoyers@efficios.com>

A rebuild of the root domains' accounting takes a CPU of the task's
cpuset for each deadline task it finds, dl_add_task_root_domain()
through dl_get_task_effective_cpus(), the first active one: a guess
that admission did not make, and three things go wrong with it.

 - The CPUs isolated by isolcpus="domain" belong to the default root
   domain, and the cpuset of a task that runs on a housekeeping CPU can
   hold them beside its housekeeping CPUs, as the root cpuset does;
   without cpusets the mask is every CPU the task may run on. The first
   active CPU of either is an isolated one where it comes first, and the
   task's bandwidth is counted in the default root domain instead of the
   one that admitted it, which underflows when the task leaves the
   class, or dies.
 - A task confined to isolated CPUs has them all taken offline, which
   nothing refuses: a deadline task of the default root domain does not
   keep the last of its CPUs online, dl_bw_deactivate() asking the root
   domain of the CPU going offline. The rebuild then finds no active CPU
   for it and BUG()s.
 - A throttled task whose CPUs went offline is moved by
   dl_task_offline_migration() to an active CPU, with its bandwidth,
   while its mask still names the offline ones: the rebuild counts it
   where the cpuset says, which is not where the move put it.

Take the CPU recorded with the task's bandwidth where it is active and
the task's cpuset still allows it: the rebuild then counts the bandwidth
where admission did, or where the last move put it, and the CPU that
dl_task_offline_migration() recorded answers for a task whose own CPUs
are offline. Where the record is of no use, its CPU offline or the
cpuset changed, take the first active CPU the cpuset allows, a
housekeeping one where it has any. The CPUs isolated at boot,
HK_TYPE_DOMAIN_BOOT, are the ones a cpuset can hold beside housekeeping
CPUs: those an isolated cpuset partition takes have a cpuset of their
own, and HK_TYPE_DOMAIN, which excludes them too, lags a change of
partitions by the rebuild that change makes,
cpuset_update_sd_hk_unlock() updating it after. Leave out a task with
no active CPU at all: the generation of "sched/deadline: Keep departing
bandwidth across a root domain rebuild" keeps the release of its
bandwidth out as well, so that nothing is taken from a root domain that
no longer counts it, and the next rebuild counts it again where it can.

Found by the Sashiko AI reviews of the first posting of this series,
the BUG() and the isolated CPU coming first, and of the second, the
housekeeping mask lagging a change of partitions and the task that
dl_task_offline_migration() moved.

Fixes: f9a25f776d78 ("cpusets: Rebuild root domain deadline accounting information")
Cc: stable@vger.kernel.org
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
---
 kernel/sched/deadline.c | 45 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index a058e0c65eca..bcf7f88b204a 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -3607,6 +3607,36 @@ 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;
+
+	dl_get_task_effective_cpus(p, msk);
+	cpumask_and(msk, msk, cpu_active_mask);
+	if (recorded >= 0 && cpu_active(recorded) &&
+	    (cpumask_test_cpu(recorded, msk) || cpumask_empty(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);
+}
+
 /* The caller should hold cpuset_mutex */
 void dl_add_task_root_domain(struct task_struct *p)
 {
@@ -3614,7 +3644,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);
 	/*
@@ -3626,10 +3655,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;
+	}
 
 	raw_spin_lock(&dl_departed_lock);
 	/*
-- 
2.47.3


  parent reply	other threads:[~2026-11-05 19:34 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 19:33 [PATCH v3 00/24] sched/deadline: bandwidth accounting fixes and selftests Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 01/24] sched: Fix cpuset_mutex double unlock in __sched_setscheduler() Mathieu Desnoyers
2026-11-05 19:51   ` Kayra Cizmeci
2026-11-05 19:54     ` Mathieu Desnoyers
2026-11-05 19:59       ` Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 02/24] sched: Refuse SCHED_FLAG_KEEP_PARAMS that would change the policy or the class Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 03/24] sched/deadline: Do not admit bandwidth for parameters that are kept Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 04/24] sched/deadline: Do not divide by zero active CPUs of a root domain Mathieu Desnoyers
2026-11-05 19:59   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 05/24] sched: Take cpuset_mutex for a deadline policy change only with pi Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 06/24] sched/deadline: Do not lose a throttled task switched out and back Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 07/24] sched/deadline: Reset the deadline and the runtime with the parameters Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 08/24] sched/deadline: Release the bandwidth of a task that leaves the class asleep Mathieu Desnoyers
2026-11-05 20:10   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 09/24] sched/deadline: Reject SCHED_DEADLINE on exited tasks Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 10/24] sched/deadline: Keep departing bandwidth across a root domain rebuild Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 11/24] sched/deadline: Do not take a waking task's bandwidth off a runqueue it left Mathieu Desnoyers
2026-11-05 20:35   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 12/24] sched/deadline: Rebuild the root domains' accounting without cpusets too Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 13/24] sched/deadline: Leave a dying task out of a rebuild of the accounting Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 14/24] sched/deadline: Record the root domain holding a task's bandwidth Mathieu Desnoyers
2026-11-05 20:50   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 15/24] sched/deadline: Move a task's bandwidth only where room was made Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 16/24] cgroup/cpuset: Wait for an attach before rebuilding the sched domains Mathieu Desnoyers
2026-11-05 20:36   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 17/24] cgroup/cpuset: Give back the bandwidth an attach did not move Mathieu Desnoyers
2026-11-05 19:33 ` Mathieu Desnoyers [this message]
2026-11-05 20:58   ` [PATCH v3 18/24] sched/deadline: Credit a rebuild to the CPU recorded with the task's bandwidth sashiko-bot
2026-11-05 19:33 ` [PATCH v3 19/24] sched/deadline: Cancel the replenishment timer with the parameters Mathieu Desnoyers
2026-11-05 21:05   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 20/24] sched/deadline: Count the bandwidth a boosted task is given Mathieu Desnoyers
2026-11-05 21:13   ` sashiko-bot
2026-11-05 19:33 ` [PATCH v3 21/24] sched/debug: Show the deadline bandwidth of each runqueue Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 22/24] selftests/sched: Add a test of SCHED_DEADLINE policy round trips Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 23/24] selftests/sched: Test SCHED_DEADLINE bandwidth across a root domain rebuild Mathieu Desnoyers
2026-11-05 19:33 ` [PATCH v3 24/24] selftests/sched: Add a test of SCHED_DEADLINE bandwidth accounting Mathieu Desnoyers
2026-11-05 21:17   ` sashiko-bot
2026-11-05 21:20 ` [PATCH v3 00/24] 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=20261105193359.1450487-19-mathieu.desnoyers@efficios.com \
    --to=mathieu.desnoyers@efficios.com \
    --cc=bigeasy@linutronix.de \
    --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=stable@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=weihengqiuu@gmail.com \
    /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®