From: Srikar Dronamraju <srikar@linux.ibm.com>
To: Kayra Cizmeci <kayracizmeci@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
LKML <linux-kernel@vger.kernel.org>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Ben Segall <bsegall@google.com>,
Juri Lelli <juri.lelli@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>,
Mel Gorman <mgorman@suse.de>,
Steven Rostedt <rostedt@goodmis.org>,
Valentin Schneider <vschneid@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>
Subject: Re: [PATCH] sched/fair: Skip sched-domain traversal when wake affine is disabled
Date: Mon, 9 Nov 2026 22:01:20 +0530 [thread overview]
Message-ID: <avH1WCeG9_O83U7N@linux.ibm.com> (raw)
In-Reply-To: <avHZrLRHmIgRu-a7@scheduler.schedules>
* Kayra Cizmeci <kayracizmeci@gmail.com> [2026-11-09 18:09:56]:
Hi Kayra,
>
> On Mon, Nov 09, 2026 at 05:35:22PM +0530, Srikar Dronamraju wrote:
> > In select_task_rq_fair(), TTWU wakeups for which wake_wide() returns
> > true, or where the waking CPU is not in the task's allowed CPU mask,
> > want_affine is set to false.
> >
> > For these wakeups, the scheduler does not perform wake-affine placement.
> > The existing code already treats this as a fast-path by exiting the
> > sched-domain walk before locating an SD_BALANCE_WAKE domain, ultimately
> > falling through to select_idle_sibling().
>
> Not before locating. If it doesn't locates SD_BALANCE_WAKE in the first
> check it just leaves.
>
> AFAICT SD_BALANCE_WAKE is not set anywhere tho.
from kernel/sched/sched.h
#define WF_TTWU 0x08 /* Wakeup; maps to SD_BALANCE_WAKE *
The code searches for WF_TTWU in lieu of SD_BALANCE_WAKE.
>
> So if you wanna do this, maybe you can do something like:
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index d4cc0caee626..b40b2eb5e577 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -10016,6 +10016,9 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> }
>
> want_affine = !wake_wide(p) && cpumask_test_cpu(cpu, p->cpus_ptr);
> +
> + if (!want_affine)
> + return select_idle_sibling(p, prev_cpu, new_cpu);
> }
Yes, this also has the same effect.
>
> for_each_domain(cpu, tmp) {
>
> >
> > However, select_task_rq_fair() still enters the sched-domain traversal
> > only to break out almost immediately. Avoid this unnecessary work by
> > jumping directly to the existing fast path when want_affine is false.
> >
> > As part of this cleanup:
> >
> > - Move want_affine into the WF_TTWU block where it is used.
> > - Skip the sched-domain traversal entirely when want_affine is false.
> > - Remove the now redundant want_affine test from the
> > SD_WAKE_AFFINE check.
> > - Remove the corresponding !want_affine loop termination logic.
> >
> > This preserves existing wakeup placement behavior while avoiding
> > unnecessary sched-domain iteration for TTWU wakeups that cannot make
> > use of wake-affine placement.
> >
> > Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
> > ---
> > kernel/sched/fair.c | 9 +++++----
> > 1 file changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > index 3ebec186f982..58ff55e093cb 100644
> > --- a/kernel/sched/fair.c
> > +++ b/kernel/sched/fair.c
> > @@ -8832,7 +8832,6 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> > struct sched_domain *tmp, *sd = NULL;
> > int cpu = smp_processor_id();
> > int new_cpu = prev_cpu;
> > - int want_affine = 0;
> > /* SD_flags and WF_flags share the first nibble */
> > int sd_flag = wake_flags & 0xF;
> >
> > @@ -8841,6 +8840,8 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> > */
> > lockdep_assert_held(&p->pi_lock);
> > if (wake_flags & WF_TTWU) {
> > + int want_affine;
> > +
> > record_wakee(p);
> >
> > if ((wake_flags & WF_CURRENT_CPU) &&
> > @@ -8855,6 +8856,8 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> > }
> >
> > want_affine = !wake_wide(p) && cpumask_test_cpu(cpu, p->cpus_ptr);
> > + if (!want_affine)
> > + goto fast_path;
> > }
> >
> > for_each_domain(cpu, tmp) {
> > @@ -8862,7 +8865,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> > * If both 'cpu' and 'prev_cpu' are part of this domain,
> > * cpu is a valid SD_WAKE_AFFINE target.
> > */
> > - if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
> > + if ((tmp->flags & SD_WAKE_AFFINE) &&
> > cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
> > if (cpu != prev_cpu)
> > new_cpu = wake_affine(tmp, p, cpu, prev_cpu, sync);
> > @@ -8878,8 +8881,6 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
> > */
> > if (tmp->flags & sd_flag)
> > sd = tmp;
> > - else if (!want_affine)
> > - break;
> > }
>
>
> This just changes the behavior.
>
> Old Code WF_FORK 1, WF_TTWU 0:
>
> want_affine = 0, so we skip the first if block in the loop then leave
> once we find a domain without our flag. And go with slow path.
>
>
> New Code:
>
> want_affine is moved away and early exit is removed. So we enter the if
> block and try to find a domain with prev_cpu. Because WF_TTWU
> is 0, we just return new_cpu. Or if we can't fimd the domain with
> prev_cpu, slow path.
>
When WF_TTWU is set, we are always suppose take the fast path.
slowpath is for WF_FORK and WF_EXEC.
>
> Cheers,
>
> Kayra
--
Thanks and Regards
Srikar Dronamraju
next prev parent reply other threads:[~2026-11-09 16:31 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 12:05 [PATCH] sched/fair: Skip sched-domain traversal when wake affine is disabled Srikar Dronamraju
2026-11-09 15:09 ` Kayra Cizmeci
2026-11-09 16:31 ` Srikar Dronamraju [this message]
2026-11-09 18:10 ` Kayra Cizmeci
2026-11-10 1:30 ` Srikar Dronamraju
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=avH1WCeG9_O83U7N@linux.ibm.com \
--to=srikar@linux.ibm.com \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=juri.lelli@redhat.com \
--cc=kayracizmeci@gmail.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@kernel.org \
--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 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.