From: K Prateek Nayak <kprateek.nayak@amd.com>
To: Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Anna-Maria Behnsen <anna-maria@linutronix.de>,
Frederic Weisbecker <frederic@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>
Cc: <linux-kernel@vger.kernel.org>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>,
"Gautham R. Shenoy" <gautham.shenoy@amd.com>,
Swapnil Sapkal <swapnil.sapkal@amd.com>,
Shrikanth Hegde <sshegde@linux.ibm.com>,
Chen Yu <yu.c.chen@intel.com>
Subject: [RESEND RFC PATCH v2 09/29] sched/fair: Rotate the CPU resposible for busy load balancing
Date: Mon, 8 Dec 2025 09:26:55 +0000 [thread overview]
Message-ID: <20251208092744.32737-9-kprateek.nayak@amd.com> (raw)
In-Reply-To: <20251208083602.31898-1-kprateek.nayak@amd.com>
The group_balance_cpu() currently always returns the fist CPU from the
group_balance_mask(). This puts the burden of busy balancing on the same
set of CPUs when the system is under heavy load.
Rotate the CPU responsilble for busy load balancing across all the CPUs
in group_balance_cpu(). The "busy_balance_cpu" in "sg->scg" shows the
CPU currently responsible for busy balancing in the group. Since
"sg->sgc" is shared by all the CPUs of group_balance_cpu(), all CPUs of
group will see the same "busy_balance_cpu".
The current "busy_balance_cpu" is responsible for updating the shared
variable with the next CPU on the mask once it is done attempting
balancing.
Although there is an unlikely chance of the current "busy_balance_cpu"
being unable to perform load balancing in a timely manner if it is
running with softirqs disabled, it is no worse than current scenario
where the first CPU of group_balance_mask() could also be unavailable
for a long time to perform load balancing.
Any hotplug / cpuset operation will rebuild the sched domain hierarchy
which will reset the "busy_balance_cpu" to the first CPU on the updated
group_balance_mask().
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
kernel/sched/fair.c | 24 +++++++++++++++++++++++-
kernel/sched/sched.h | 1 +
kernel/sched/topology.c | 5 ++++-
3 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8f5745495974..e3935903d9c5 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -11747,7 +11747,7 @@ static int should_we_balance(struct lb_env *env)
if (idle_smt != -1)
return idle_smt == env->dst_cpu;
- /* Are we the first CPU of this group ? */
+ /* Are we the busy load balancing CPU of this group ? */
return group_balance_cpu(sg) == env->dst_cpu;
}
@@ -11773,6 +11773,22 @@ static void update_lb_imbalance_stat(struct lb_env *env, struct sched_domain *sd
}
}
+static void update_busy_balance_cpu(int this_cpu, struct lb_env *env)
+{
+ struct sched_group *group = env->sd->groups;
+ int balance_cpu = group_balance_cpu(group);
+
+ /*
+ * Only the current CPU responsible for busy load balancing
+ * should update the "busy_balance_cpu" for next instance.
+ */
+ if (this_cpu != balance_cpu)
+ return;
+
+ balance_cpu = cpumask_next_wrap(balance_cpu, group_balance_mask(group));
+ WRITE_ONCE(group->sgc->busy_balance_cpu, balance_cpu);
+}
+
/*
* This flag serializes load-balancing passes over large domains
* (above the NODE topology level) - only one load-balancing instance
@@ -12075,6 +12091,12 @@ static int sched_balance_rq(int this_cpu, struct rq *this_rq,
out:
if (need_unlock)
atomic_set_release(&sched_balance_running, 0);
+ /*
+ * If this was a successful busy balancing attempt,
+ * update the "busy_balance_cpu" of the group.
+ */
+ if (!idle && continue_balancing)
+ update_busy_balance_cpu(this_cpu, &env);
return ld_moved;
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index b419a4d98461..659e712f348f 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2100,6 +2100,7 @@ struct sched_group_capacity {
unsigned long max_capacity; /* Max per-CPU capacity in group */
unsigned long next_update;
int imbalance; /* XXX unrelated to capacity but shared group state */
+ int busy_balance_cpu;
int id;
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 14be90af9761..8870b38d4072 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -810,7 +810,7 @@ enum s_alloc {
*/
int group_balance_cpu(struct sched_group *sg)
{
- return cpumask_first(group_balance_mask(sg));
+ return READ_ONCE(sg->sgc->busy_balance_cpu);
}
@@ -992,6 +992,8 @@ static void init_overlap_sched_group(struct sched_domain *sd,
cpu = cpumask_first(mask);
sg->sgc = *per_cpu_ptr(sdd->sgc, cpu);
+ sg->sgc->busy_balance_cpu = cpu;
+
if (atomic_inc_return(&sg->sgc->ref) == 1)
cpumask_copy(group_balance_mask(sg), mask);
else
@@ -1211,6 +1213,7 @@ static struct sched_group *get_group(int cpu, struct sd_data *sdd)
sg = *per_cpu_ptr(sdd->sg, cpu);
sg->sgc = *per_cpu_ptr(sdd->sgc, cpu);
+ sg->sgc->busy_balance_cpu = cpu;
/* Increase refcounts for claim_allocations: */
already_visited = atomic_inc_return(&sg->ref) > 1;
--
2.43.0
next prev parent reply other threads:[~2025-12-08 9:30 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-08 9:26 [RESEND RFC PATCH v2 00/29] sched/fair: Push-based load balancing K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 01/29] sched/fair: Simplify set_cpu_sd_state_*() with guards K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 02/29] sched/fair: Use rq->nohz_tick_stopped in update_nohz_stats() K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 03/29] sched/topology: Optimize sd->shared allocation and assignment K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 04/29] sched/fair: Simplify the entry condition for update_idle_cpu_scan() K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 05/29] sched/fair: Simplity SIS_UTIL handling in select_idle_cpu() K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 06/29] cpumask: Introduce for_each_cpu_and_wrap() and bitfield helpers K Prateek Nayak
2025-12-12 21:03 ` Yury Norov
2025-12-08 9:26 ` [RESEND RFC PATCH v2 07/29] sched/fair: Use for_each_cpu_and_wrap() in select_idle_capacity() K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 08/29] sched/fair: Use for_each_cpu_and_wrap() in select_idle_cpu() K Prateek Nayak
2025-12-08 9:26 ` K Prateek Nayak [this message]
2025-12-08 9:26 ` [RESEND RFC PATCH v2 10/29] sched/fair: Use xchg() to set sd->nohz_idle state K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 11/29] sched/topology: Attach new hierarchy in rq_attach_root() K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 12/29] sched/fair: Fixup sd->nohz_idle state during hotplug / cpuset K Prateek Nayak
2025-12-08 9:26 ` [RESEND RFC PATCH v2 13/29] sched/fair: Account idle cpus instead of busy cpus in sd->shared K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 14/29] sched/topology: Introduce fallback sd->shared assignment K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 15/29] sched/topology: Introduce percpu sd_nohz for nohz state tracking K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 16/29] sched/topology: Introduce "nohz_idle_cpus_mask" in sd->shared K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 17/29] sched/topology: Introduce "nohz_shared_list" to keep track of sd->shared K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 18/29] sched/fair: Reorder the barrier in nohz_balance_enter_idle() K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 19/29] sched/fair: Extract the main _nohz_idle_balance() loop into a helper K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 20/29] sched/fair: Convert find_new_ilb() to use nohz_shared_list K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 21/29] sched/fair: Introduce sched_asym_prefer_idle() for ILB kick K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 22/29] sched/fair: Convert sched_balance_nohz_idle() to use nohz_shared_list K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 23/29] sched/fair: Remove "nohz.idle_cpus_mask" K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 24/29] sched/fair: Optimize global "nohz.nr_cpus" tracking K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 25/29] sched/topology: Add basic debug information for "nohz_shared_list" K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 26/29] [EXPERIMENTAL] sched/fair: Add push task framework K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 27/29] [EXPERIMENTAL] sched/fair: Proactive idle balance using push mechanism K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 28/29] [EXPERIMENTAL] sched/fair: Add a local counter to rate limit task push K Prateek Nayak
2025-12-08 12:33 ` Christian Loehle
2025-12-08 17:35 ` K Prateek Nayak
2025-12-08 9:27 ` [RESEND RFC PATCH v2 29/29] [EXPERIMENTAL] sched/fair: Faster alternate for intra-NUMA newidle balance K Prateek Nayak
2025-12-08 14:04 ` [RESEND RFC PATCH v2 00/29] sched/fair: Push-based load balancing Shrikanth Hegde
2025-12-08 17:36 ` K Prateek Nayak
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=20251208092744.32737-9-kprateek.nayak@amd.com \
--to=kprateek.nayak@amd.com \
--cc=anna-maria@linutronix.de \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=frederic@kernel.org \
--cc=gautham.shenoy@amd.com \
--cc=juri.lelli@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=sshegde@linux.ibm.com \
--cc=swapnil.sapkal@amd.com \
--cc=tglx@linutronix.de \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
--cc=yu.c.chen@intel.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;
as well as URLs for NNTP newsgroup(s).