* [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
@ 2026-06-29 8:35 Lucas de Lima Nóbrega
2026-06-29 14:05 ` Lukasz Luba
2026-06-29 15:16 ` Rafael J. Wysocki (Intel)
0 siblings, 2 replies; 12+ messages in thread
From: Lucas de Lima Nóbrega @ 2026-06-29 8:35 UTC (permalink / raw)
To: rafael, viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot
Cc: dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel,
Lucas de Lima Nóbrega
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.
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.
Signed-off-by: Lucas de Lima Nóbrega <lucaslnobrega38@gmail.com>
---
Documentation/admin-guide/pm/intel_pstate.rst | 9 ++++--
Documentation/scheduler/sched-energy.rst | 7 ++++-
kernel/sched/topology.c | 28 +++++++++++++++++--
3 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst
index 25fe5d88f..c8fef1e60 100644
--- a/Documentation/admin-guide/pm/intel_pstate.rst
+++ b/Documentation/admin-guide/pm/intel_pstate.rst
@@ -409,13 +409,16 @@ Energy-Aware Scheduling Support
If ``CONFIG_ENERGY_MODEL`` has been set during kernel configuration and
``intel_pstate`` runs on a hybrid processor without SMT, in addition to enabling
:ref:`CAS` it registers an Energy Model for the processor. This allows the
-Energy-Aware Scheduling (EAS) support to be enabled in the CPU scheduler if
-``schedutil`` is used as the ``CPUFreq`` governor which requires ``intel_pstate``
-to operate in the :ref:`passive mode <passive_mode>`.
+Energy-Aware Scheduling (EAS) support to be enabled in the CPU scheduler.
The Energy Model registered by ``intel_pstate`` is artificial (that is, it is
based on abstract cost values and it does not include any real power numbers)
and it is relatively simple to avoid unnecessary computations in the scheduler.
+Because of that, EAS does not require ``schedutil`` to be used as the
+``CPUFreq`` governor in this case: the cost ranking it relies on does not
+depend on the governor tracking utilization when requesting frequencies, so
+EAS works the same way regardless of whether ``intel_pstate`` operates in the
+active or in the :ref:`passive mode <passive_mode>`.
There is a performance domain in it for every CPU in the system and the cost
values for these performance domains have been chosen so that running a task on
a less performant (small) CPU appears to be always cheaper than running that
diff --git a/Documentation/scheduler/sched-energy.rst b/Documentation/scheduler/sched-energy.rst
index 4e47aaf10..c23ca226d 100644
--- a/Documentation/scheduler/sched-energy.rst
+++ b/Documentation/scheduler/sched-energy.rst
@@ -379,7 +379,12 @@ Consequently, the only sane governor to use together with EAS is schedutil,
because it is the only one providing some degree of consistency between
frequency requests and energy predictions.
-Using EAS with any other governor than schedutil is not supported.
+Using EAS with any other governor than schedutil is not supported, unless the
+EM in use is artificial (see EM_PERF_DOMAIN_ARTIFICIAL). An artificial EM only
+encodes a cost ranking between CPUs/OPPs instead of a real power table, so it
+does not make any claim about energy use at a specific OPP and its conclusions
+do not depend on the governor actually tracking utilization when requesting
+frequencies.
6.5 Scale-invariant utilization signals
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 5847b83d9..124a4bb4d 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -212,6 +212,27 @@ static unsigned int sysctl_sched_energy_aware = 1;
static DEFINE_MUTEX(sched_energy_mutex);
static bool sched_energy_update;
+/*
+ * An artificial EM (see EM_PERF_DOMAIN_ARTIFICIAL) only encodes a cost
+ * ranking between CPUs and does not claim to predict energy use at any
+ * particular OPP. Unlike a real power-based EM, its conclusions do not
+ * rely on the active governor tracking utilization when selecting
+ * frequencies, so the schedutil requirement below does not apply to it.
+ */
+static bool perf_domains_are_artificial(const struct cpumask *cpu_mask)
+{
+ int i;
+
+ for_each_cpu(i, cpu_mask) {
+ struct em_perf_domain *pd = em_cpu_get(i);
+
+ if (!pd || !em_is_artificial(pd))
+ return false;
+ }
+
+ return true;
+}
+
static bool sched_is_eas_possible(const struct cpumask *cpu_mask)
{
bool any_asym_capacity = false;
@@ -249,7 +270,8 @@ static bool sched_is_eas_possible(const struct cpumask *cpu_mask)
return false;
}
- if (!cpufreq_ready_for_eas(cpu_mask)) {
+ if (!cpufreq_ready_for_eas(cpu_mask) &&
+ !perf_domains_are_artificial(cpu_mask)) {
if (sched_debug()) {
pr_info("rd %*pbl: Checking EAS: cpufreq is not ready\n",
cpumask_pr_args(cpu_mask));
@@ -403,7 +425,9 @@ static void sched_energy_set(bool has_eas)
* 1. an Energy Model (EM) is available;
* 2. the SD_ASYM_CPUCAPACITY flag is set in the sched_domain hierarchy.
* 3. no SMT is detected.
- * 4. schedutil is driving the frequency of all CPUs of the rd;
+ * 4. schedutil is driving the frequency of all CPUs of the rd, or the EM
+ * of all of them is artificial (i.e. a cost ranking rather than a
+ * real power table, see EM_PERF_DOMAIN_ARTIFICIAL);
* 5. frequency invariance support is present;
*/
static bool build_perf_domains(const struct cpumask *cpu_map)
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
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)
1 sibling, 1 reply; 12+ messages in thread
From: Lukasz Luba @ 2026-06-29 14:05 UTC (permalink / raw)
To: Lucas de Lima Nóbrega
Cc: dietmar.eggemann, rostedt, vincent.guittot, mingo, bsegall,
mgorman, vschneid, kprateek.nayak, corbet, skhan, linux-pm,
linux-doc, linux-kernel, juri.lelli, rafael, viresh.kumar, peterz
On 6/29/26 09:35, Lucas de Lima Nóbrega 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.
>
> 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
When frequency is picked autonomously then EAS and energy estimations
don't make sense IMHO.
Do you have any data from experiments how it runs?
Regards,
Lukasz
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
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 15:16 ` Rafael J. Wysocki (Intel)
2026-06-29 19:06 ` Rafael J. Wysocki
2026-06-29 21:12 ` Lucas Lima
1 sibling, 2 replies; 12+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-06-29 15:16 UTC (permalink / raw)
To: Lucas de Lima Nóbrega
Cc: rafael, viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
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.
> Signed-off-by: Lucas de Lima Nóbrega <lucaslnobrega38@gmail.com>
> ---
> Documentation/admin-guide/pm/intel_pstate.rst | 9 ++++--
> Documentation/scheduler/sched-energy.rst | 7 ++++-
> kernel/sched/topology.c | 28 +++++++++++++++++--
> 3 files changed, 38 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst
> index 25fe5d88f..c8fef1e60 100644
> --- a/Documentation/admin-guide/pm/intel_pstate.rst
> +++ b/Documentation/admin-guide/pm/intel_pstate.rst
> @@ -409,13 +409,16 @@ Energy-Aware Scheduling Support
> If ``CONFIG_ENERGY_MODEL`` has been set during kernel configuration and
> ``intel_pstate`` runs on a hybrid processor without SMT, in addition to enabling
> :ref:`CAS` it registers an Energy Model for the processor. This allows the
> -Energy-Aware Scheduling (EAS) support to be enabled in the CPU scheduler if
> -``schedutil`` is used as the ``CPUFreq`` governor which requires ``intel_pstate``
> -to operate in the :ref:`passive mode <passive_mode>`.
> +Energy-Aware Scheduling (EAS) support to be enabled in the CPU scheduler.
>
> The Energy Model registered by ``intel_pstate`` is artificial (that is, it is
> based on abstract cost values and it does not include any real power numbers)
> and it is relatively simple to avoid unnecessary computations in the scheduler.
> +Because of that, EAS does not require ``schedutil`` to be used as the
> +``CPUFreq`` governor in this case: the cost ranking it relies on does not
> +depend on the governor tracking utilization when requesting frequencies, so
> +EAS works the same way regardless of whether ``intel_pstate`` operates in the
> +active or in the :ref:`passive mode <passive_mode>`.
> There is a performance domain in it for every CPU in the system and the cost
> values for these performance domains have been chosen so that running a task on
> a less performant (small) CPU appears to be always cheaper than running that
> diff --git a/Documentation/scheduler/sched-energy.rst b/Documentation/scheduler/sched-energy.rst
> index 4e47aaf10..c23ca226d 100644
> --- a/Documentation/scheduler/sched-energy.rst
> +++ b/Documentation/scheduler/sched-energy.rst
> @@ -379,7 +379,12 @@ Consequently, the only sane governor to use together with EAS is schedutil,
> because it is the only one providing some degree of consistency between
> frequency requests and energy predictions.
>
> -Using EAS with any other governor than schedutil is not supported.
> +Using EAS with any other governor than schedutil is not supported, unless the
> +EM in use is artificial (see EM_PERF_DOMAIN_ARTIFICIAL). An artificial EM only
> +encodes a cost ranking between CPUs/OPPs instead of a real power table, so it
> +does not make any claim about energy use at a specific OPP and its conclusions
> +do not depend on the governor actually tracking utilization when requesting
> +frequencies.
>
>
> 6.5 Scale-invariant utilization signals
> diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
> index 5847b83d9..124a4bb4d 100644
> --- a/kernel/sched/topology.c
> +++ b/kernel/sched/topology.c
> @@ -212,6 +212,27 @@ static unsigned int sysctl_sched_energy_aware = 1;
> static DEFINE_MUTEX(sched_energy_mutex);
> static bool sched_energy_update;
>
> +/*
> + * An artificial EM (see EM_PERF_DOMAIN_ARTIFICIAL) only encodes a cost
> + * ranking between CPUs and does not claim to predict energy use at any
> + * particular OPP. Unlike a real power-based EM, its conclusions do not
> + * rely on the active governor tracking utilization when selecting
> + * frequencies, so the schedutil requirement below does not apply to it.
> + */
> +static bool perf_domains_are_artificial(const struct cpumask *cpu_mask)
> +{
> + int i;
> +
> + for_each_cpu(i, cpu_mask) {
> + struct em_perf_domain *pd = em_cpu_get(i);
I would do
if (!pd)
continue;
here because the CPUs without a PD simply don't matter.
Also, is any synchronization needed for this?
And should it go into the EM code?
> +
> + if (!pd || !em_is_artificial(pd))
> + return false;
> + }
> +
> + return true;
> +}
> +
> static bool sched_is_eas_possible(const struct cpumask *cpu_mask)
> {
> bool any_asym_capacity = false;
> @@ -249,7 +270,8 @@ static bool sched_is_eas_possible(const struct cpumask *cpu_mask)
> return false;
> }
>
> - if (!cpufreq_ready_for_eas(cpu_mask)) {
> + if (!cpufreq_ready_for_eas(cpu_mask) &&
> + !perf_domains_are_artificial(cpu_mask)) {
> if (sched_debug()) {
> pr_info("rd %*pbl: Checking EAS: cpufreq is not ready\n",
> cpumask_pr_args(cpu_mask));
> @@ -403,7 +425,9 @@ static void sched_energy_set(bool has_eas)
> * 1. an Energy Model (EM) is available;
> * 2. the SD_ASYM_CPUCAPACITY flag is set in the sched_domain hierarchy.
> * 3. no SMT is detected.
> - * 4. schedutil is driving the frequency of all CPUs of the rd;
> + * 4. schedutil is driving the frequency of all CPUs of the rd, or the EM
> + * of all of them is artificial (i.e. a cost ranking rather than a
> + * real power table, see EM_PERF_DOMAIN_ARTIFICIAL);
> * 5. frequency invariance support is present;
> */
> static bool build_perf_domains(const struct cpumask *cpu_map)
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-29 15:16 ` Rafael J. Wysocki (Intel)
@ 2026-06-29 19:06 ` Rafael J. Wysocki
2026-06-30 8:11 ` Lucas Lima
2026-06-29 21:12 ` Lucas Lima
1 sibling, 1 reply; 12+ messages in thread
From: Rafael J. Wysocki @ 2026-06-29 19:06 UTC (permalink / raw)
To: Lucas de Lima Nóbrega
Cc: viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
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);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-29 14:05 ` Lukasz Luba
@ 2026-06-29 19:07 ` Lucas Lima
0 siblings, 0 replies; 12+ messages in thread
From: Lucas Lima @ 2026-06-29 19:07 UTC (permalink / raw)
To: Lukasz Luba
Cc: dietmar.eggemann, rostedt, vincent.guittot, mingo, bsegall,
mgorman, vschneid, kprateek.nayak, corbet, skhan, linux-pm,
linux-doc, linux-kernel, juri.lelli, rafael, viresh.kumar, peterz
Em seg., 29 de jun. de 2026 às 11:05, Lukasz Luba
<lukasz.luba@arm.com> escreveu:
>
>
>
> On 6/29/26 09:35, Lucas de Lima Nóbrega 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.
> >
> > 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
>
> When frequency is picked autonomously then EAS and energy estimations
> don't make sense IMHO.
>
> Do you have any data from experiments how it runs?
>
> Regards,
> Lukasz
Through my testings, HWP does seem follow an strictly non decreasing
duty-cycle to freq curve, with or without frequency clamping and turbo
boost activated. For me, that feels enough to justify the use of the
simplified energy model already implemented.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-29 15:16 ` Rafael J. Wysocki (Intel)
2026-06-29 19:06 ` Rafael J. Wysocki
@ 2026-06-29 21:12 ` Lucas Lima
2026-06-30 12:47 ` Rafael J. Wysocki (Intel)
1 sibling, 1 reply; 12+ messages in thread
From: Lucas Lima @ 2026-06-29 21:12 UTC (permalink / raw)
To: Rafael J. Wysocki (Intel)
Cc: viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
Em seg., 29 de jun. de 2026 às 12:16, Rafael J. Wysocki (Intel)
<rafael@kernel.org> escreveu:
>
> 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).
You're right, and I want to walk back the "artificial EM doesn't need
this" framing entirely -- it doesn't survive your example. What I want
to argue instead is narrower: that even though intel_pstate active
mode tracks demand much more weakly than schedutil, the specific
conclusion this simplified EM's cost ranking relies on (E-cores cost
less than P-cores at matched conditions) still holds up against
measured energy, and that's a different, more modest claim than "OPP
tracks utilization closely enough for per-bin accuracy."
I measured the actual frequency behavior on this test machine (one
P-core, one E-core, isolated, stress-ng --cpu-load duty cycles at
20/40/60/80/100%, turbostat Bzy_MHz = average frequency only during
the busy portion of each cycle) under three regimes:
20% 40% 60% 80% 100% span
passive+schedutil P 2523 2879 3786 4537 4567 2044
E 2335 2416 2574 3070 3399 1064
active EPP=balance P 2225 2285 2497 2646 2778 553
E 2101 2215 2375 2462 2555 454
active EPP=perf P 4483 4519 4496 4537 4564 81
E 3364 3377 3380 3387 3399 35
It is visible now that intel_pstate active
mode does *not* track demand anywhere near as tightly as schedutil,
and i don't think that claim survives scrutiny, dropping it.
What does survive, I think, is narrower: E-cores measured consistently
cheaper per unit of completed work than P-cores, across every matched-
parallelism configuration I tested (data below), regardless of which
exact OPP HWP autonomously picked underneath. I don't have data on
idle-state residency to know truly whether the race-to-idle behavior under
EPP=performance recovers any of that gap through deeper C-states --
that's an open question I haven't tested.
1 core alone: P 7.27 J/unit E 6.25 J/unit (P +16%)
1 core, packed x2: P 7.24 J/unit E 6.13 J/unit (P +18%)
2 cores, spread: P 4.84 J/unit E 3.82 J/unit (P +27%)
P consistently costs more than E for the same completed work at every
matched parallelism level I tried. Separately, I also measured that
spreading work across more E-cores is itself far more efficient than
packing it onto fewer (8 E-cores spread: 1.74 J/unit vs the same total
work packed onto 1 E-core: 6.10 J/unit. In fact, this is the most
efficient placement --
even better than global spreading) -- I also have traced
find_energy_efficient_cpu()
produced spread placement in practice under this patch with real tasks,
and it roughly does follow this heavy preference for E cores during light load.
Note: P cores occasionally seem to spike, likely due to misfit tasks
which are larger
than E core capacity when nosmt=force is active (512). To place E
cores capacities
at half of P cores' feels weird, as the vast majority of workloads enjoy only a
40-60% performance disparity between them both (the outliers observed are
mostly float point heavy tasks, software ipc class 2).
>
> > 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.
Given the data above, I don't think I can honestly word that
declaration as "as good as schedutil" -- it isn't, by a factor of
2-25x depending on EPP. If a flag like this still makes sense, I'd
want its justification to say something narrower: "this driver's
internal governor, combined with this EM's coarse type-based ranking,
still produces correct placement decisions in practice" rather than
claiming OPP-tracking parity. I'm not sure if that's a distinction
that belongs in the flag's contract itself, or just in this
patch's commit message -- happy to go either way, or to test more
if that would help decide.
>
> > Signed-off-by: Lucas de Lima Nóbrega <lucaslnobrega38@gmail.com>
> > ---
> > Documentation/admin-guide/pm/intel_pstate.rst | 9 ++++--
> > Documentation/scheduler/sched-energy.rst | 7 ++++-
> > kernel/sched/topology.c | 28 +++++++++++++++++--
> > 3 files changed, 38 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst
> > index 25fe5d88f..c8fef1e60 100644
> > --- a/Documentation/admin-guide/pm/intel_pstate.rst
> > +++ b/Documentation/admin-guide/pm/intel_pstate.rst
> > @@ -409,13 +409,16 @@ Energy-Aware Scheduling Support
> > If ``CONFIG_ENERGY_MODEL`` has been set during kernel configuration and
> > ``intel_pstate`` runs on a hybrid processor without SMT, in addition to enabling
> > :ref:`CAS` it registers an Energy Model for the processor. This allows the
> > -Energy-Aware Scheduling (EAS) support to be enabled in the CPU scheduler if
> > -``schedutil`` is used as the ``CPUFreq`` governor which requires ``intel_pstate``
> > -to operate in the :ref:`passive mode <passive_mode>`.
> > +Energy-Aware Scheduling (EAS) support to be enabled in the CPU scheduler.
> >
> > The Energy Model registered by ``intel_pstate`` is artificial (that is, it is
> > based on abstract cost values and it does not include any real power numbers)
> > and it is relatively simple to avoid unnecessary computations in the scheduler.
> > +Because of that, EAS does not require ``schedutil`` to be used as the
> > +``CPUFreq`` governor in this case: the cost ranking it relies on does not
> > +depend on the governor tracking utilization when requesting frequencies, so
> > +EAS works the same way regardless of whether ``intel_pstate`` operates in the
> > +active or in the :ref:`passive mode <passive_mode>`.
> > There is a performance domain in it for every CPU in the system and the cost
> > values for these performance domains have been chosen so that running a task on
> > a less performant (small) CPU appears to be always cheaper than running that
> > diff --git a/Documentation/scheduler/sched-energy.rst b/Documentation/scheduler/sched-energy.rst
> > index 4e47aaf10..c23ca226d 100644
> > --- a/Documentation/scheduler/sched-energy.rst
> > +++ b/Documentation/scheduler/sched-energy.rst
> > @@ -379,7 +379,12 @@ Consequently, the only sane governor to use together with EAS is schedutil,
> > because it is the only one providing some degree of consistency between
> > frequency requests and energy predictions.
> >
> > -Using EAS with any other governor than schedutil is not supported.
> > +Using EAS with any other governor than schedutil is not supported, unless the
> > +EM in use is artificial (see EM_PERF_DOMAIN_ARTIFICIAL). An artificial EM only
> > +encodes a cost ranking between CPUs/OPPs instead of a real power table, so it
> > +does not make any claim about energy use at a specific OPP and its conclusions
> > +do not depend on the governor actually tracking utilization when requesting
> > +frequencies.
> >
> >
> > 6.5 Scale-invariant utilization signals
> > diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
> > index 5847b83d9..124a4bb4d 100644
> > --- a/kernel/sched/topology.c
> > +++ b/kernel/sched/topology.c
> > @@ -212,6 +212,27 @@ static unsigned int sysctl_sched_energy_aware = 1;
> > static DEFINE_MUTEX(sched_energy_mutex);
> > static bool sched_energy_update;
> >
> > +/*
> > + * An artificial EM (see EM_PERF_DOMAIN_ARTIFICIAL) only encodes a cost
> > + * ranking between CPUs and does not claim to predict energy use at any
> > + * particular OPP. Unlike a real power-based EM, its conclusions do not
> > + * rely on the active governor tracking utilization when selecting
> > + * frequencies, so the schedutil requirement below does not apply to it.
> > + */
> > +static bool perf_domains_are_artificial(const struct cpumask *cpu_mask)
> > +{
> > + int i;
> > +
> > + for_each_cpu(i, cpu_mask) {
> > + struct em_perf_domain *pd = em_cpu_get(i);
>
> I would do
>
> if (!pd)
> continue;
>
> here because the CPUs without a PD simply don't matter.
That's fair. I will be updating the code to ignore cpus with no perf
domain. I also want to discuss whether or not is it worth it to
aggregate E clusters inside the same perf domain, as they share the
same L2 cache and
migrations are likely easier.
>
> Also, is any synchronization needed for this?
No additional sync besides what is already in use today. In fact, this
very pointer is dereferenced the same way in other paths of the
kernel.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-29 19:06 ` Rafael J. Wysocki
@ 2026-06-30 8:11 ` Lucas Lima
2026-06-30 13:06 ` Rafael J. Wysocki (Intel)
0 siblings, 1 reply; 12+ messages in thread
From: Lucas Lima @ 2026-06-30 8:11 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
Em seg., 29 de jun. de 2026 às 16:06, Rafael J. Wysocki
<rafael@kernel.org> escreveu:
>
> 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).
It does work, thank you.
>
> 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?
About that specific topic i do not have any testing data, but it felt
like schedutil drains more battery than pstate active (likely due to
worse c-states management) and presents more stutters in general usage
(I would guess it's slower to react to load changes). After bypassing schedutil
those very observations were gone, and the responsiveness of the system
looked very similar to EAS disabled, pstate active. Since EAS does
prioritize spreading
onto E cores, which do consume less energy by my testing, IMHO it's
almost too good
to be leaving it unused.
I also want to point out that gaming (mainly minecraft) stutters a lot more with
EAS on, even when pstate is set to active. So i wonder what do you think about
capturing the system power mode (currently only clamps frequency) and
disabling eas_compatible when set to "performance"? That would need
updating cpufreq_policy, but feels reasonable to let the user disable EAS
for latency sensitive tasks, since E cores struggle at those.
I also want to point out that gaming (mainly Minecraft) stutters a lot
more with EAS,
even when pstate is set to active. So I wonder what you think about
capturing the
platform power profile (via the platform_profile subsystem) and
disabling eas_compatible
when set to "performance"? That would need a notifier from
platform_profile to re-evaluate eas_compatible
across active policies when the profile changes at runtime, but feels
reasonable to let the
user disable EAS for latency-sensitive tasks, since E-cores struggle at those.
I know that for now, my observations are only anecdotal, but if needed
I'm eager to test those assumptions!
>
> ---
> 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);
>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-29 21:12 ` Lucas Lima
@ 2026-06-30 12:47 ` Rafael J. Wysocki (Intel)
0 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-06-30 12:47 UTC (permalink / raw)
To: Lucas Lima
Cc: Rafael J. Wysocki (Intel), viresh.kumar, mingo, peterz,
juri.lelli, vincent.guittot, dietmar.eggemann, rostedt, bsegall,
mgorman, vschneid, kprateek.nayak, corbet, skhan, linux-pm,
linux-doc, linux-kernel
On Mon, Jun 29, 2026 at 11:13 PM Lucas Lima <lucaslnobrega38@gmail.com> wrote:
>
> Em seg., 29 de jun. de 2026 às 12:16, Rafael J. Wysocki (Intel)
> <rafael@kernel.org> escreveu:
> >
> > 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).
>
> You're right, and I want to walk back the "artificial EM doesn't need
> this" framing entirely -- it doesn't survive your example. What I want
> to argue instead is narrower: that even though intel_pstate active
> mode tracks demand much more weakly than schedutil, the specific
> conclusion this simplified EM's cost ranking relies on (E-cores cost
> less than P-cores at matched conditions) still holds up against
> measured energy, and that's a different, more modest claim than "OPP
> tracks utilization closely enough for per-bin accuracy."
>
> I measured the actual frequency behavior on this test machine (one
> P-core, one E-core, isolated, stress-ng --cpu-load duty cycles at
> 20/40/60/80/100%, turbostat Bzy_MHz = average frequency only during
> the busy portion of each cycle) under three regimes:
>
> 20% 40% 60% 80% 100% span
> passive+schedutil P 2523 2879 3786 4537 4567 2044
> E 2335 2416 2574 3070 3399 1064
> active EPP=balance P 2225 2285 2497 2646 2778 553
> E 2101 2215 2375 2462 2555 454
> active EPP=perf P 4483 4519 4496 4537 4564 81
> E 3364 3377 3380 3387 3399 35
>
> It is visible now that intel_pstate active
> mode does *not* track demand anywhere near as tightly as schedutil,
> and i don't think that claim survives scrutiny, dropping it.
>
> What does survive, I think, is narrower: E-cores measured consistently
> cheaper per unit of completed work than P-cores, across every matched-
> parallelism configuration I tested (data below), regardless of which
> exact OPP HWP autonomously picked underneath. I don't have data on
> idle-state residency to know truly whether the race-to-idle behavior under
> EPP=performance recovers any of that gap through deeper C-states --
> that's an open question I haven't tested.
>
> 1 core alone: P 7.27 J/unit E 6.25 J/unit (P +16%)
> 1 core, packed x2: P 7.24 J/unit E 6.13 J/unit (P +18%)
> 2 cores, spread: P 4.84 J/unit E 3.82 J/unit (P +27%)
>
> P consistently costs more than E for the same completed work at every
> matched parallelism level I tried. Separately, I also measured that
> spreading work across more E-cores is itself far more efficient than
> packing it onto fewer (8 E-cores spread: 1.74 J/unit vs the same total
> work packed onto 1 E-core: 6.10 J/unit. In fact, this is the most
> efficient placement --
> even better than global spreading) -- I also have traced
> find_energy_efficient_cpu()
> produced spread placement in practice under this patch with real tasks,
> and it roughly does follow this heavy preference for E cores during light load.
> Note: P cores occasionally seem to spike, likely due to misfit tasks
> which are larger
> than E core capacity when nosmt=force is active (512). To place E
> cores capacities
> at half of P cores' feels weird, as the vast majority of workloads enjoy only a
> 40-60% performance disparity between them both (the outliers observed are
> mostly float point heavy tasks, software ipc class 2).
>
> >
> > > 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.
>
> Given the data above, I don't think I can honestly word that
> declaration as "as good as schedutil" -- it isn't, by a factor of
> 2-25x depending on EPP. If a flag like this still makes sense, I'd
> want its justification to say something narrower: "this driver's
> internal governor, combined with this EM's coarse type-based ranking,
> still produces correct placement decisions in practice" rather than
> claiming OPP-tracking parity.
Yes, that sounds better.
> I'm not sure if that's a distinction
> that belongs in the flag's contract itself, or just in this
> patch's commit message -- happy to go either way, or to test more
> if that would help decide.
I think that the point regarding the need to combine the given
governor with a "matching" EM is fair and it needs to be documented.
I'll try to find suitable wording.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-30 8:11 ` Lucas Lima
@ 2026-06-30 13:06 ` Rafael J. Wysocki (Intel)
2026-06-30 18:15 ` Lucas Lima
0 siblings, 1 reply; 12+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-06-30 13:06 UTC (permalink / raw)
To: Lucas Lima
Cc: Rafael J. Wysocki, viresh.kumar, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid, kprateek.nayak, corbet, skhan, linux-pm, linux-doc,
linux-kernel
On Tue, Jun 30, 2026 at 10:11 AM Lucas Lima <lucaslnobrega38@gmail.com> wrote:
>
> Em seg., 29 de jun. de 2026 às 16:06, Rafael J. Wysocki
> <rafael@kernel.org> escreveu:
> >
> > 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).
>
> It does work, thank you.
Great, thanks!
So this approach is more straightforward IMV and that's why I prefer it.
I'll need to revise the new flag description so it mentions the need
for a "matching" EM to produce reasonable results and there are a few
intel_pstate patches in-flight, so this one will need to be rebased.
It also needs a changelog, of course.
> >
> > 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?
>
> About that specific topic i do not have any testing data, but it felt
> like schedutil drains more battery than pstate active (likely due to
> worse c-states management) and presents more stutters in general usage
> (I would guess it's slower to react to load changes). After bypassing schedutil
> those very observations were gone, and the responsiveness of the system
> looked very similar to EAS disabled, pstate active. Since EAS does
> prioritize spreading
> onto E cores, which do consume less energy by my testing, IMHO it's
> almost too good
> to be leaving it unused.
Fair enough.
> I also want to point out that gaming (mainly minecraft) stutters a lot more with
> EAS on, even when pstate is set to active. So i wonder what do you think about
> capturing the system power mode (currently only clamps frequency) and
> disabling eas_compatible when set to "performance"? That would need
> updating cpufreq_policy, but feels reasonable to let the user disable EAS
> for latency sensitive tasks, since E cores struggle at those.
Switching the governor (or policy if you will) to "performance" on any
CPU should cause eas_compatible to be cleared for it due to the
cpu->policy != CPUFREQ_POLICY_PERFORMANCE check and then the scheduler
will refuse to use EAS after rebuilding the sched domains.
Or do you mean something else?
> I know that for now, my observations are only anecdotal, but if needed
> I'm eager to test those assumptions!
So it would be good to have some data indicating that it is beneficial
to use EAS when intel_pstate operates in the active mode ("powersave"
policy).
Also, enabling EAS by default for the active mode may be problematic
because people may see (and report) performance regressions due to it.
OTOH, EAS can be disabled via sysctl, so that may not be a big deal.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-30 13:06 ` Rafael J. Wysocki (Intel)
@ 2026-06-30 18:15 ` Lucas Lima
2026-07-02 21:27 ` Lucas Lima
0 siblings, 1 reply; 12+ messages in thread
From: Lucas Lima @ 2026-06-30 18:15 UTC (permalink / raw)
To: Rafael J. Wysocki (Intel)
Cc: viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
Em ter., 30 de jun. de 2026 às 10:07, Rafael J. Wysocki (Intel)
<rafael@kernel.org> escreveu:
>
> On Tue, Jun 30, 2026 at 10:11 AM Lucas Lima <lucaslnobrega38@gmail.com> wrote:
> >
> > Em seg., 29 de jun. de 2026 às 16:06, Rafael J. Wysocki
> > <rafael@kernel.org> escreveu:
> > >
> > > 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).
> >
> > It does work, thank you.
>
> Great, thanks!
>
> So this approach is more straightforward IMV and that's why I prefer it.
>
> I'll need to revise the new flag description so it mentions the need
> for a "matching" EM to produce reasonable results and there are a few
> intel_pstate patches in-flight, so this one will need to be rebased.
> It also needs a changelog, of course.
>
> > >
> > > 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?
> >
> > About that specific topic i do not have any testing data, but it felt
> > like schedutil drains more battery than pstate active (likely due to
> > worse c-states management) and presents more stutters in general usage
> > (I would guess it's slower to react to load changes). After bypassing schedutil
> > those very observations were gone, and the responsiveness of the system
> > looked very similar to EAS disabled, pstate active. Since EAS does
> > prioritize spreading
> > onto E cores, which do consume less energy by my testing, IMHO it's
> > almost too good
> > to be leaving it unused.
>
> Fair enough.
>
> > I also want to point out that gaming (mainly minecraft) stutters a lot more with
> > EAS on, even when pstate is set to active. So i wonder what do you think about
> > capturing the system power mode (currently only clamps frequency) and
> > disabling eas_compatible when set to "performance"? That would need
> > updating cpufreq_policy, but feels reasonable to let the user disable EAS
> > for latency sensitive tasks, since E cores struggle at those.
>
> Switching the governor (or policy if you will) to "performance" on any
> CPU should cause eas_compatible to be cleared for it due to the
> cpu->policy != CPUFREQ_POLICY_PERFORMANCE check and then the scheduler
> will refuse to use EAS after rebuilding the sched domains.
>
> Or do you mean something else?
I actually mean performance mode in platform profile really, as it's the more
straightforward way for the user to request for more responsiveness
from the system.
For now, putting platform profile at performance does not change the
governor from
powersave, and as such, EAS is not disabled. A notifier from platform_profile
to re-evaluate eas_compatible when the profile changes would address this."
>
> > I know that for now, my observations are only anecdotal, but if needed
> > I'm eager to test those assumptions!
>
> So it would be good to have some data indicating that it is beneficial
> to use EAS when intel_pstate operates in the active mode ("powersave"
> policy).
Will be on it.
>
> Also, enabling EAS by default for the active mode may be problematic
> because people may see (and report) performance regressions due to it.
> OTOH, EAS can be disabled via sysctl, so that may not be a big deal.
I feel that concern further motivates my proposal. I would not expect
the average user to use sysctl to change EAS or even to know
about cpufreq governors at all, so linking EAS to platform profiles
already exposed by the desktop might avoid complaints.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-06-30 18:15 ` Lucas Lima
@ 2026-07-02 21:27 ` Lucas Lima
2026-07-06 9:05 ` Christian Loehle
0 siblings, 1 reply; 12+ messages in thread
From: Lucas Lima @ 2026-07-02 21:27 UTC (permalink / raw)
To: Rafael J. Wysocki (Intel)
Cc: viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
After some testing I found out schedutil is indeed slower to react to load
changes compared to pstate active.
The methodology was to empty a cpu, run a serial float recurrence
(kept non-vectorizable
on purpose, to isolate frequency ramp-up rather than throughput headroom)
and compare the average throughput over several initial time windows
against the steady-state throughput in order to measure the CPU frequency
ramp-up delay under pstate active and schedutil.
### P-core
pstate-eas-balanced
pstate-eas-performance schedutil-eas-balanced
schedutil-eas-performance
------------------------------------------------------------------------------------------------------------------------------------------
Ramp-up (average throughput at time window / steady):
0-0.005s (%) 70.6 99.4
59.7 61.3
0-0.01s (%) 83.0 99.5
60.2 62.1
0-0.02s (%) 91.3 99.5
62.9 65.7
0-0.05s (%) 96.7 99.8
74.8 77.6
0-0.1s (%) 98.6 99.9
86.9 88.7
0-0.5s (%) 100.0 100.1
97.4 97.8
0-1.0s (%) 100.2 100.1
98.7 98.9
Convergence to 95% (ms) 5 0
52 47
Steady-state:
Throughput (Mops/s) 649.8 654.4
652.3 651.7
Energy:
Average Power (W) 9.01 8.98
9.10 9.07
Efficiency (J/Gop) 13.889 13.735
14.000 13.961
### E-core
pstate-eas-balanced
pstate-eas-performance schedutil-eas-balanced
schedutil-eas-performance
------------------------------------------------------------------------------------------------------------------------------------------
Ramp-up (average throughput at time window / steady):
0-0.005s (%) 75.6 99.0
62.3 57.9
0-0.01s (%) 85.1 99.1
62.2 58.8
0-0.02s (%) 92.4 99.3
64.5 61.0
0-0.05s (%) 97.0 99.7
72.9 69.2
0-0.1s (%) 98.6 99.9
84.8 82.1
0-0.5s (%) 99.8 100.0
96.9 96.4
0-1.0s (%) 100.0 100.0
98.5 98.2
Convergence to 95% (ms) 8 0
67 72
Steady-state:
Throughput (Mops/s) 540.6 540.8
540.1 539.7
Energy:
Average Power (W) 5.46 5.47
5.61 5.51
Efficiency (J/Gop) 10.119 10.125
10.426 10.241
That alone might make it worth it to use pstate active alongside EAS, as
responsiveness gains are noticeable while busy energy consumption is similar.
Furthermore, I implemented an EPP based EAS compatibility selection: when
EPP is set to 0 (performance), eas_compatible is set to false regardless
of the active cpufreq driver mode -- this also overrides schedutil's own
eas_compatible assignment in sugov_init()/sugov_exit() when running in
passive mode. IMHO that makes more sense than gating only on the governor,
as users selecting the performance power profile are looking for
responsiveness above all, independently of intel_pstate or governor settings.
It's also worth noting that governors already have the ability to change
EPP on their own (via intel_pstate_hwp_set()'s save/restore logic for
CPUFREQ_POLICY_PERFORMANCE), which can lead to a state where the desktop's
power profile indicator becomes inconsistent with the actual EPP value:
1. Switch governor: powersave -> performance
(intel_pstate saves the current EPP internally and forces EPP to 0)
2. Switch power profile: balanced -> performance
(EPP is explicitly written as 0 again; no visible change, since it
was already 0)
3. Switch governor: performance -> powersave
(intel_pstate restores the EPP to balanced,
because the current EPP still reads as 0 and the
restore heuristic cannot tell that this 0 was an explicit choice
rather than the still-forced value from step 1)
After step 3, EAS becomes re-enabled, since EPP is no longer "performance"
-- but the desktop still shows "performance" as the active power profile,
since nothing told power-profiles-daemon that the EPP changed underneath
it. This isn't something my patch introduces, it's an existing property
of intel_pstate's governor-triggered EPP save/restore, but it is relevant
here.
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 8f5ab9fa3..6d7133b94 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -791,6 +791,18 @@
cpufreq_freq_attr_ro(energy_performance_available_preferences);
static struct cpufreq_driver intel_pstate;
+static inline void update_eas_compatibility(struct cpufreq_policy
*policy, struct cpudata *cpu)
+{
+ bool eas_compatible_was = policy->eas_compatible;
+
+ policy->eas_compatible = hwp_is_hybrid &&
+ cpu->policy != CPUFREQ_POLICY_PERFORMANCE &&
+ intel_pstate_get_epp(cpu, 0) != HWP_EPP_PERFORMANCE;
+
+ if (policy->eas_compatible != eas_compatible_was)
+ em_rebuild_sched_domains();
+}
+
static ssize_t store_energy_performance_preference(
struct cpufreq_policy *policy, const char *buf, size_t count)
{
@@ -856,6 +868,8 @@ static ssize_t store_energy_performance_preference(
mutex_unlock(&intel_pstate_limits_lock);
+ update_eas_compatibility(policy, cpu);
+
return ret ?: count;
}
@@ -2922,10 +2936,7 @@ static int intel_pstate_set_policy(struct
cpufreq_policy *policy)
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;
- if (policy->eas_compatible)
- em_rebuild_sched_domains();
+ update_eas_compatibility(policy, cpu);
}
/*
* policy->cur is never updated with the intel_pstate driver, but it
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] sched/topology: Allow EAS without schedutil for artificial Energy Models
2026-07-02 21:27 ` Lucas Lima
@ 2026-07-06 9:05 ` Christian Loehle
0 siblings, 0 replies; 12+ messages in thread
From: Christian Loehle @ 2026-07-06 9:05 UTC (permalink / raw)
To: Lucas Lima, Rafael J. Wysocki (Intel)
Cc: viresh.kumar, mingo, peterz, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, corbet, skhan, linux-pm, linux-doc, linux-kernel
On 7/2/26 22:27, Lucas Lima wrote:
> After some testing I found out schedutil is indeed slower to react to load
> changes compared to pstate active.
>
> The methodology was to empty a cpu, run a serial float recurrence
> (kept non-vectorizable
> on purpose, to isolate frequency ramp-up rather than throughput headroom)
> and compare the average throughput over several initial time windows
> against the steady-state throughput in order to measure the CPU frequency
> ramp-up delay under pstate active and schedutil.
You might be interested in rt-app for more complex experiments along those lines.
>
> ### P-core
> pstate-eas-balanced
> pstate-eas-performance schedutil-eas-balanced
> schedutil-eas-performance
> ------------------------------------------------------------------------------------------------------------------------------------------
> Ramp-up (average throughput at time window / steady):
> 0-0.005s (%) 70.6 99.4
> 59.7 61.3
> 0-0.01s (%) 83.0 99.5
> 60.2 62.1
> 0-0.02s (%) 91.3 99.5
> 62.9 65.7
> 0-0.05s (%) 96.7 99.8
> 74.8 77.6
> 0-0.1s (%) 98.6 99.9
> 86.9 88.7
> 0-0.5s (%) 100.0 100.1
> 97.4 97.8
> 0-1.0s (%) 100.2 100.1
> 98.7 98.9
> Convergence to 95% (ms) 5 0
> 52 47
> Steady-state:
> Throughput (Mops/s) 649.8 654.4
> 652.3 651.7
> Energy:
> Average Power (W) 9.01 8.98
> 9.10 9.07
> Efficiency (J/Gop) 13.889 13.735
> 14.000 13.961
>
> ### E-core
> pstate-eas-balanced
> pstate-eas-performance schedutil-eas-balanced
> schedutil-eas-performance
> ------------------------------------------------------------------------------------------------------------------------------------------
> Ramp-up (average throughput at time window / steady):
> 0-0.005s (%) 75.6 99.0
> 62.3 57.9
> 0-0.01s (%) 85.1 99.1
> 62.2 58.8
> 0-0.02s (%) 92.4 99.3
> 64.5 61.0
> 0-0.05s (%) 97.0 99.7
> 72.9 69.2
> 0-0.1s (%) 98.6 99.9
> 84.8 82.1
> 0-0.5s (%) 99.8 100.0
> 96.9 96.4
> 0-1.0s (%) 100.0 100.0
> 98.5 98.2
> Convergence to 95% (ms) 8 0
> 67 72
> Steady-state:
> Throughput (Mops/s) 540.6 540.8
> 540.1 539.7
> Energy:
> Average Power (W) 5.46 5.47
> 5.61 5.51
> Efficiency (J/Gop) 10.119 10.125
> 10.426 10.241
>
Thanks for the data, is this 1000HZ?
Rampup is one thing, the vast difference is obviously when tasks are migrated,
which EAS is very eager to do on wakeup, sugov 'knows' the right OPP immediately,
HWP needs to run through the same wakeup again, and during that window you're
energy calculations are bogus.
> That alone might make it worth it to use pstate active alongside EAS, as
> responsiveness gains are noticeable while busy energy consumption is similar.
>
> Furthermore, I implemented an EPP based EAS compatibility selection: when
> EPP is set to 0 (performance), eas_compatible is set to false regardless
> of the active cpufreq driver mode -- this also overrides schedutil's own
> eas_compatible assignment in sugov_init()/sugov_exit() when running in
> passive mode. IMHO that makes more sense than gating only on the governor,
> as users selecting the performance power profile are looking for
> responsiveness above all, independently of intel_pstate or governor settings.
>
> It's also worth noting that governors already have the ability to change
> EPP on their own (via intel_pstate_hwp_set()'s save/restore logic for
> CPUFREQ_POLICY_PERFORMANCE), which can lead to a state where the desktop's
> power profile indicator becomes inconsistent with the actual EPP value:
>
> 1. Switch governor: powersave -> performance
> (intel_pstate saves the current EPP internally and forces EPP to 0)
>
> 2. Switch power profile: balanced -> performance
> (EPP is explicitly written as 0 again; no visible change, since it
> was already 0)
>
> 3. Switch governor: performance -> powersave
> (intel_pstate restores the EPP to balanced,
> because the current EPP still reads as 0 and the
> restore heuristic cannot tell that this 0 was an explicit choice
> rather than the still-forced value from step 1)
>
> After step 3, EAS becomes re-enabled, since EPP is no longer "performance"
> -- but the desktop still shows "performance" as the active power profile,
> since nothing told power-profiles-daemon that the EPP changed underneath
> it. This isn't something my patch introduces, it's an existing property
> of intel_pstate's governor-triggered EPP save/restore, but it is relevant
> here.
I think this is a separate ownership problem, but IMO the user gets a choice,
either have a userspace daemon take care of these settings or set it themselves,
i.e. step 1 mustn't happen (I'm reading that correctly that 1. wasn't set
through power-profiles-daemon? If it was that seems a bug in power-profiles-daemon).
>
> diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
> index 8f5ab9fa3..6d7133b94 100644
> --- a/drivers/cpufreq/intel_pstate.c
> +++ b/drivers/cpufreq/intel_pstate.c
> @@ -791,6 +791,18 @@
> cpufreq_freq_attr_ro(energy_performance_available_preferences);
>
> static struct cpufreq_driver intel_pstate;
>
> +static inline void update_eas_compatibility(struct cpufreq_policy
> *policy, struct cpudata *cpu)
> +{
> + bool eas_compatible_was = policy->eas_compatible;
> +
> + policy->eas_compatible = hwp_is_hybrid &&
> + cpu->policy != CPUFREQ_POLICY_PERFORMANCE &&
> + intel_pstate_get_epp(cpu, 0) != HWP_EPP_PERFORMANCE;
> +
> + if (policy->eas_compatible != eas_compatible_was)
> + em_rebuild_sched_domains();
> +}
> +
> static ssize_t store_energy_performance_preference(
> struct cpufreq_policy *policy, const char *buf, size_t count)
> {
> @@ -856,6 +868,8 @@ static ssize_t store_energy_performance_preference(
>
> mutex_unlock(&intel_pstate_limits_lock);
>
> + update_eas_compatibility(policy, cpu);
> +
> return ret ?: count;
> }
>
> @@ -2922,10 +2936,7 @@ static int intel_pstate_set_policy(struct
> cpufreq_policy *policy)
> 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;
> - if (policy->eas_compatible)
> - em_rebuild_sched_domains();
> + update_eas_compatibility(policy, cpu);
> }
> /*
> * policy->cur is never updated with the intel_pstate driver, but it
>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-07-06 9:05 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox