From: "Rafael J. Wysocki" <rafael@kernel.org>
To: "Lucas de Lima Nóbrega" <lucaslnobrega38@gmail.com>
Cc: viresh.kumar@linaro.org, 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, corbet@lwn.net,
skhan@linuxfoundation.org, linux-pm@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
Date: Mon, 29 Jun 2026 21:06:10 +0200 [thread overview]
Message-ID: <6021784.DvuYhMxLoT@rafael.j.wysocki> (raw)
In-Reply-To: <CAJZ5v0iVD90XPsWgT8B+fw9vmFRZTVL7MasPP-=Ci0OdUmNR=A@mail.gmail.com>
On Monday, June 29, 2026 5:16:17 PM CEST Rafael J. Wysocki (Intel) wrote:
> On Mon, Jun 29, 2026 at 10:36 AM Lucas de Lima Nóbrega
> <lucaslnobrega38@gmail.com> wrote:
> >
> > EAS currently refuses to enable energy-aware scheduling on a root
> > domain unless schedutil is the active CPUFreq governor for all of its
> > CPUs (cpufreq_ready_for_eas()). This requirement exists to protect the
> > accuracy of the energy estimate: EAS predicts the OPP a CPU will run
> > at from its utilization, which is only meaningful if the active
> > governor actually requests OPPs that way, and schedutil is the only
> > one that does.
> >
> > That requirement does not apply to artificial Energy Models
> > (EM_PERF_DOMAIN_ARTIFICIAL). An artificial EM is built from a
> > get_cost() callback instead of real power numbers, and only encodes a
> > cost ranking between CPUs (e.g. P-cores cost more than E-cores at a
> > given utilization). It never claims to predict real energy use at any
> > specific OPP, so there is no per-OPP accuracy for the governor
> > requirement to protect, regardless of which governor is in control or
> > whether it tracks utilization at all.
>
> But it is still about comparing the cost of running on different CPUs
> at different performance levels.
>
> For instance, say the scale-invariant utilization of a task is 256 and
> it can run either by itself on a P-core, or with another task whose
> utilization is 128 on an E-core, and say the P-core's and E-core's
> capacity is 1024 and 512, respectively.
>
> Say the cost function tells EAS that running a P-core at 1/4 of the
> capacity is cheaper than running an E-core at 3/4 capacity, so it will
> pick up the P-core to run that task, but if cpufreq ramps up the
> frequency of the P-core to the max when the task gets to it, it may
> actually turn out to be more expensive.
>
> This means that EAS still has an expectation regarding cpufreq which
> is that it will generally tend to run tasks at the performance level
> corresponding to the sum of their scale-invariant utilization at least
> roughly.
>
> IIUC this actually has nothing to do with whether or not the energy
> model used by EAS is artificial. The schedutil requirement is about
> choosing a performance level proportional to the utilization (which
> schedutil generally tends to do by design).
>
> > intel_pstate registers exactly this kind of artificial EM for hybrid
> > (P/E-core) systems without SMT, regardless of whether it operates in
> > active or passive mode. In active mode it never uses schedutil, since
> > HWP picks frequency autonomously, so on these systems EAS never
> > engages even though SD_ASYM_CPUCAPACITY, frequency invariance and the
> > EM are all in place: find_energy_efficient_cpu() is never reached
> > because is_rd_overutilized() is hardcoded to true whenever
> > sched_energy_enabled() is false. cppc_cpufreq registers the same kind
> > of ranking-only artificial EM and is affected the same way with any
> > non-schedutil governor.
> >
> > Allow EAS to be enabled when every CPU's EM in the root domain is
> > artificial, even when schedutil is not the active governor.
> >
> > Tested on a Raptor Lake-P laptop with nosmt=force and intel_pstate in
> > active/HWP mode: find_energy_efficient_cpu() was never called before
> > this change (confirmed via the sched_overutilized_tp tracepoint and
> > ftrace) and is exercised as expected afterwards.
>
> If this is about allowing EAS to work with intel_pstate running in the
> active mode, you may argue that what the processor firmware is doing
> when intel_pstate runs in the active mode is not much different from
> what schedutil would do. So a driver implementing an internal
> governor (that is, using the .set_policy() callback) would need to
> declare that its internal governor is as good as schedutil from EAS'
> perspective and so it will pass the "cpufreq readiness" check.
And I have a prototype patch (on top of 7.2-rc1) doing this which is
appended.
I wonder if it works for you (that is, if it allows intel_pstate and EAS to
work together both with schedutil and when intel_pstate operates in the
active mode with the "powersave" policy on your system).
Also I wonder why exactly you want intel_pstate in the active mode to
work with EAS. Do you see any significant improvement in that case?
---
drivers/cpufreq/cpufreq.c | 2 +-
drivers/cpufreq/intel_pstate.c | 11 +++++++++++
include/linux/cpufreq.h | 16 +++++++---------
kernel/sched/cpufreq_schedutil.c | 7 ++-----
4 files changed, 21 insertions(+), 15 deletions(-)
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -3058,7 +3058,7 @@ static bool cpufreq_policy_is_good_for_e
return false;
}
- return sugov_is_governor(policy);
+ return policy->eas_compatible;
}
bool cpufreq_ready_for_eas(const struct cpumask *cpu_mask)
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -2921,6 +2921,9 @@ static int intel_pstate_set_policy(struc
if (!hwp_boost)
intel_pstate_clear_update_util_hook(policy->cpu);
intel_pstate_hwp_set(policy->cpu);
+
+ policy->eas_compatible = hwp_is_hybrid &&
+ cpu->policy != CPUFREQ_POLICY_PERFORMANCE;
}
/*
* policy->cur is never updated with the intel_pstate driver, but it
@@ -2930,6 +2933,9 @@ static int intel_pstate_set_policy(struc
mutex_unlock(&intel_pstate_limits_lock);
+ if (policy->eas_compatible)
+ em_rebuild_sched_domains();
+
return 0;
}
@@ -3030,6 +3036,11 @@ static void intel_pstate_cpu_exit(struct
pr_debug("CPU %d exiting\n", policy->cpu);
policy->fast_switch_possible = false;
+
+ if (policy->eas_compatible) {
+ policy->eas_compatible = false;
+ em_rebuild_sched_domains();
+ }
}
static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -118,6 +118,13 @@ struct cpufreq_policy {
bool strict_target;
/*
+ * Set if the current governor meets EAS' expectations regarding
+ * performance scaling (that is, it selects performance levels
+ * proportional to CPU utilization at least roughly).
+ */
+ bool eas_compatible;
+
+ /*
* Set if inefficient frequencies were found in the frequency table.
* This indicates if the relation flag CPUFREQ_RELATION_E can be
* honored.
@@ -657,15 +664,6 @@ module_exit(__governor##_exit)
struct cpufreq_governor *cpufreq_default_governor(void);
struct cpufreq_governor *cpufreq_fallback_governor(void);
-#ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL
-bool sugov_is_governor(struct cpufreq_policy *policy);
-#else
-static inline bool sugov_is_governor(struct cpufreq_policy *policy)
-{
- return false;
-}
-#endif
-
static inline void cpufreq_policy_apply_limits(struct cpufreq_policy *policy)
{
if (policy->max < policy->cur)
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -797,6 +797,7 @@ out:
* Schedutil is the preferred governor for EAS, so rebuild sched domains
* on governor changes to make sure the scheduler knows about them.
*/
+ policy->eas_compatible = true;
em_rebuild_sched_domains();
mutex_unlock(&global_tunables_lock);
return 0;
@@ -839,6 +840,7 @@ static void sugov_exit(struct cpufreq_po
sugov_policy_free(sg_policy);
cpufreq_disable_fast_switch(policy);
+ policy->eas_compatible = false;
em_rebuild_sched_domains();
}
@@ -931,9 +933,4 @@ struct cpufreq_governor *cpufreq_default
}
#endif
-bool sugov_is_governor(struct cpufreq_policy *policy)
-{
- return policy->governor == &schedutil_gov;
-}
-
cpufreq_governor_init(schedutil_gov);
next prev parent reply other threads:[~2026-06-29 19:06 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 8:35 [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models Lucas de Lima Nóbrega
2026-06-29 14:05 ` Lukasz Luba
2026-06-29 19:07 ` Lucas Lima
2026-06-29 15:16 ` Rafael J. Wysocki (Intel)
2026-06-29 19:06 ` Rafael J. Wysocki [this message]
2026-06-30 8:11 ` Lucas Lima
2026-06-30 13:06 ` Rafael J. Wysocki (Intel)
2026-06-30 18:15 ` Lucas Lima
2026-07-02 21:27 ` Lucas Lima
2026-07-06 9:05 ` Christian Loehle
2026-06-29 21:12 ` Lucas Lima
2026-06-30 12:47 ` Rafael J. Wysocki (Intel)
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=6021784.DvuYhMxLoT@rafael.j.wysocki \
--to=rafael@kernel.org \
--cc=bsegall@google.com \
--cc=corbet@lwn.net \
--cc=dietmar.eggemann@arm.com \
--cc=juri.lelli@redhat.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lucaslnobrega38@gmail.com \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=skhan@linuxfoundation.org \
--cc=vincent.guittot@linaro.org \
--cc=viresh.kumar@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