From: Kayra Cizmeci <kayracizmeci@gmail.com>
To: Li kunyu <likunyu@open-hieco.net>
Cc: mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kprateek.nayak@amd.com,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] sched/fair: Distribute burst-woken tasks when rq depth reaches 3x average
Date: Thu, 5 Nov 2026 19:46:50 +0300 [thread overview]
Message-ID: <auypmYsIO08V3avZ@scheduler.schedules> (raw)
In-Reply-To: <5e26b0b2-0b87-da79-9cb5-b471c9ebf77a@open-hieco.net>
On Thu, Nov 05, 2026 at 09:43:07AM +0800, Li kunyu wrote:
> Hi Kayra,
>
> On 2026/11/5 2:10, Kayra Cizmeci wrote:
> >
> > Hi!
> >
> > On Wed, Nov 04, 2026 at 05:18:42PM +0800, Li kunyu wrote:
> >
> > FWIW, This doesn't apply to the mainline:
> >
> > Patch failed at 0001 sched/fair: Distribute burst-woken tasks when rq depth reaches 3x average
> > error: patch failed: kernel/sched/fair.c:9972
> > error: kernel/sched/fair.c: patch does not apply
>
> Today, I updated the warehouse branch to the latest version, addressed the
> identified issues, and performed another thorough test.
>
> >> When a task burst-wakes a large number of tasks in a short period, tasks
> >> can pile up on a single CPU regardless of whether the system has idle
> >> CPUs or NO_HZ enabled.
> >>
> >> Track the average runqueue depth (scaled by SCHED_CAPACITY_SCALE to
> >> preserve fractional precision) in root_domain during the periodic
> >> load-balance pass.
> >>
> >> In select_task_rq_fair(), when the target runqueue depth reaches 3x the
> >> system-wide average, fall back to cpumask_any_and_distribute(p->cpus_ptr,
> >> cpu_active_mask) to rotate waking tasks across allowed CPUs and reset the
> >> periodic load balance intervals so regular load balancing can promptly
> >> smooth out the distribution.
> >>
> >> Suggested-by: Peter Zijlstra <peterz@infradead.org>
> >> Link: https://lore.kernel.org/all/20261021125419.GK2823843@noisy.programming.kicks-ass.net/
> >> Signed-off-by: Li kunyu <likunyu@open-hieco.net>
> >> ---
> >> kernel/sched/fair.c | 70 ++++++++++++++++++++++++++++++++++++++---
> >> kernel/sched/sched.h | 3 ++
> >> kernel/sched/topology.c | 2 ++
> >> 3 files changed, 71 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> >> index 6e005f1e8dc9..e4d278ac46c4 100644
> >> --- a/kernel/sched/fair.c
> >> +++ b/kernel/sched/fair.c
> >> @@ -9903,6 +9903,38 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
> >> return target;
> >> }
> >>
> >> +/*
> >> + * Check if a CPU's rq depth reaches 3x the system-wide average tracked
> >> + * in root_domain (scaled by SCHED_CAPACITY_SCALE, floored at 1 task).
> >> + */
> >> +static inline bool rq_burst_overloaded(int cpu)
> >> +{
> >> + struct rq *rq = cpu_rq(cpu);
> >> + unsigned long avg;
> >> +
> >> + if (unlikely(!rq->rd))
> >> + return false;
> >> +
> >> + avg = max_t(unsigned long, READ_ONCE(rq->rd->avg_nr_running),
> >> + SCHED_CAPACITY_SCALE);
> >> +
> >> + return (READ_ONCE(rq->nr_running) << SCHED_CAPACITY_SHIFT) >= avg * 3;
> >> +}
> >> +
> >> +static inline void reset_periodic_lb_interval(int cpu)
> >> +{
> >> + struct sched_domain *sd;
> >> +
> >> + /*
> >> + * Only the most basic values are updated here to avoid excessive
> >> + * cost.
> >> + */
> >> + for_each_domain(cpu, sd) {
> >> + if (READ_ONCE(sd->balance_interval) > sd->min_interval)
> >> + WRITE_ONCE(sd->balance_interval, sd->min_interval);
> >> + }
> >> +}
> >> +
> >> /*
> >> * select_task_rq_fair: Select target runqueue for the waking task in domains
> >> * that have the relevant SD flag set. In practice, this is SD_BALANCE_WAKE,
> >> @@ -9972,11 +10004,19 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> >>
> >> /* Slow path */
> >> if (unlikely(sd))
> >> - return sched_balance_find_dst_cpu(sd, p, cpu, prev_cpu, sd_flag);
> >> -
> >> + new_cpu = sched_balance_find_dst_cpu(sd, p, cpu, prev_cpu, sd_flag);
> >> /* Fast path */
> >> - if (wake_flags & WF_TTWU)
> >> - return select_idle_sibling(p, prev_cpu, new_cpu);
> >> + else if (wake_flags & WF_TTWU)
> >> + new_cpu = select_idle_sibling(p, prev_cpu, new_cpu);
> >> +
> >> + if (unlikely(rq_burst_overloaded(new_cpu))) {
> >> + int dist_cpu = cpumask_any_and_distribute(p->cpus_ptr, cpu_active_mask);
> >> +
> >> + if (likely(dist_cpu < nr_cpumask_bits)) {
> >> + reset_periodic_lb_interval(new_cpu);
> >
> > Why are we calling this for new_cpu?
>
> Here, the existing logic is reused, with new_cpu used as the final return value.
It's not used as the final return value. We return dist_cpu not new_cpu.
Look below :-).
> It remains unclear whether this approach is appropriate. If it causes no
> practical impact, it seems reasonable to keep it unchanged.
>
> >> + return dist_cpu;
> >> + }
> >> + }
> >>
Well, if we chose dist_cpu instead of new_cpu why we are calling
reset_periodic_lb_interval() thingie for new_cpu?
Even calling it for dist_cpu is questionable.
Because:
sched_balance_domains() gets the interval value from
get_sd_balance_interval(). get_sd_balance_interval() reads the value
from sd->balance_interval (The value we are resetting) and multiplies it
by busy_factor if the cpu_busy bool parameter is true.
sched_balance_domains() calls sched_balance_rq() if jiffies is bigger or equal to
last_balance + interval.
Now as you can see, we make the interval value bigger when the CPU is
busy. In your path, if the new_cpu is not the picked CPU calling this
makes no sense. Because if we didn't picked it, it already means that
it's busy or atleast worse than the other options.
sched_balance_rq() already tries to pull the tasks to the given CPU at
first place.
If we really wanna do that, atleast call it for dist_cpu (the returned CPU) not
for the CPU that lost.
Or am I getting something wrong?
Cheers,
Kayra
next prev parent reply other threads:[~2026-11-05 16:46 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 9:18 Li kunyu
2026-11-04 9:34 ` Li kunyu
2026-11-04 18:10 ` Kayra Cizmeci
2026-11-05 1:43 ` Li kunyu
2026-11-05 16:46 ` Kayra Cizmeci [this message]
2026-11-06 1:58 ` Li kunyu
2026-11-05 3:44 ` K Prateek Nayak
2026-11-05 11:24 ` Li kunyu
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=auypmYsIO08V3avZ@scheduler.schedules \
--to=kayracizmeci@gmail.com \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=juri.lelli@redhat.com \
--cc=kprateek.nayak@amd.com \
--cc=likunyu@open-hieco.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.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®