@@ -221,6 +221,7 @@ struct global_params {
221221 * @sched_flags: Store scheduler flags for possible cross CPU update
222222 * @hwp_boost_min: Last HWP boosted min performance
223223 * @suspended: Whether or not the driver has been suspended.
224+ * @pd_registered: Set when a perf domain is registered for this CPU.
224225 * @hwp_notify_work: workqueue for HWP notifications.
225226 *
226227 * This structure stores per CPU instance data for all CPUs.
@@ -260,6 +261,9 @@ struct cpudata {
260261 unsigned int sched_flags ;
261262 u32 hwp_boost_min ;
262263 bool suspended ;
264+ #ifdef CONFIG_ENERGY_MODEL
265+ bool pd_registered ;
266+ #endif
263267 struct delayed_work hwp_notify_work ;
264268};
265269
@@ -303,6 +307,7 @@ static bool hwp_is_hybrid;
303307
304308static struct cpufreq_driver * intel_pstate_driver __read_mostly ;
305309
310+ #define INTEL_PSTATE_CORE_SCALING 100000
306311#define HYBRID_SCALING_FACTOR_ADL 78741
307312#define HYBRID_SCALING_FACTOR_MTL 80000
308313#define HYBRID_SCALING_FACTOR_LNL 86957
@@ -311,7 +316,7 @@ static int hybrid_scaling_factor;
311316
312317static inline int core_get_scaling (void )
313318{
314- return 100000 ;
319+ return INTEL_PSTATE_CORE_SCALING ;
315320}
316321
317322#ifdef CONFIG_ACPI
@@ -948,12 +953,124 @@ static struct cpudata *hybrid_max_perf_cpu __read_mostly;
948953 */
949954static DEFINE_MUTEX (hybrid_capacity_lock );
950955
956+ #ifdef CONFIG_ENERGY_MODEL
957+ #define HYBRID_EM_STATE_COUNT 4
958+
959+ static int hybrid_active_power (struct device * dev , unsigned long * power ,
960+ unsigned long * freq )
961+ {
962+ /*
963+ * Create "utilization bins" of 0-40%, 40%-60%, 60%-80%, and 80%-100%
964+ * of the maximum capacity such that two CPUs of the same type will be
965+ * regarded as equally attractive if the utilization of each of them
966+ * falls into the same bin, which should prevent tasks from being
967+ * migrated between them too often.
968+ *
969+ * For this purpose, return the "frequency" of 2 for the first
970+ * performance level and otherwise leave the value set by the caller.
971+ */
972+ if (!* freq )
973+ * freq = 2 ;
974+
975+ /* No power information. */
976+ * power = EM_MAX_POWER ;
977+
978+ return 0 ;
979+ }
980+
981+ static int hybrid_get_cost (struct device * dev , unsigned long freq ,
982+ unsigned long * cost )
983+ {
984+ struct pstate_data * pstate = & all_cpu_data [dev -> id ]-> pstate ;
985+ struct cpu_cacheinfo * cacheinfo = get_cpu_cacheinfo (dev -> id );
986+
987+ /*
988+ * The smaller the perf-to-frequency scaling factor, the larger the IPC
989+ * ratio between the given CPU and the least capable CPU in the system.
990+ * Regard that IPC ratio as the primary cost component and assume that
991+ * the scaling factors for different CPU types will differ by at least
992+ * 5% and they will not be above INTEL_PSTATE_CORE_SCALING.
993+ *
994+ * Add the freq value to the cost, so that the cost of running on CPUs
995+ * of the same type in different "utilization bins" is different.
996+ */
997+ * cost = div_u64 (100ULL * INTEL_PSTATE_CORE_SCALING , pstate -> scaling ) + freq ;
998+ /*
999+ * Increase the cost slightly for CPUs able to access L3 to avoid
1000+ * touching it in case some other CPUs of the same type can do the work
1001+ * without it.
1002+ */
1003+ if (cacheinfo ) {
1004+ unsigned int i ;
1005+
1006+ /* Check if L3 cache is there. */
1007+ for (i = 0 ; i < cacheinfo -> num_leaves ; i ++ ) {
1008+ if (cacheinfo -> info_list [i ].level == 3 ) {
1009+ * cost += 2 ;
1010+ break ;
1011+ }
1012+ }
1013+ }
1014+
1015+ return 0 ;
1016+ }
1017+
1018+ static bool hybrid_register_perf_domain (unsigned int cpu )
1019+ {
1020+ static const struct em_data_callback cb
1021+ = EM_ADV_DATA_CB (hybrid_active_power , hybrid_get_cost );
1022+ struct cpudata * cpudata = all_cpu_data [cpu ];
1023+ struct device * cpu_dev ;
1024+
1025+ /*
1026+ * Registering EM perf domains without enabling asymmetric CPU capacity
1027+ * support is not really useful and one domain should not be registered
1028+ * more than once.
1029+ */
1030+ if (!hybrid_max_perf_cpu || cpudata -> pd_registered )
1031+ return false;
1032+
1033+ cpu_dev = get_cpu_device (cpu );
1034+ if (!cpu_dev )
1035+ return false;
1036+
1037+ if (em_dev_register_pd_no_update (cpu_dev , HYBRID_EM_STATE_COUNT , & cb ,
1038+ cpumask_of (cpu ), false))
1039+ return false;
1040+
1041+ cpudata -> pd_registered = true;
1042+
1043+ return true;
1044+ }
1045+
1046+ static void hybrid_register_all_perf_domains (void )
1047+ {
1048+ unsigned int cpu ;
1049+
1050+ for_each_online_cpu (cpu )
1051+ hybrid_register_perf_domain (cpu );
1052+ }
1053+
1054+ static void hybrid_update_perf_domain (struct cpudata * cpu )
1055+ {
1056+ if (cpu -> pd_registered )
1057+ em_adjust_cpu_capacity (cpu -> cpu );
1058+ }
1059+ #else /* !CONFIG_ENERGY_MODEL */
1060+ static inline bool hybrid_register_perf_domain (unsigned int cpu ) { return false; }
1061+ static inline void hybrid_register_all_perf_domains (void ) {}
1062+ static inline void hybrid_update_perf_domain (struct cpudata * cpu ) {}
1063+ #endif /* CONFIG_ENERGY_MODEL */
1064+
9511065static void hybrid_set_cpu_capacity (struct cpudata * cpu )
9521066{
9531067 arch_set_cpu_capacity (cpu -> cpu , cpu -> capacity_perf ,
9541068 hybrid_max_perf_cpu -> capacity_perf ,
9551069 cpu -> capacity_perf ,
9561070 cpu -> pstate .max_pstate_physical );
1071+ hybrid_update_perf_domain (cpu );
1072+
1073+ topology_set_cpu_scale (cpu -> cpu , arch_scale_cpu_capacity (cpu -> cpu ));
9571074
9581075 pr_debug ("CPU%d: perf = %u, max. perf = %u, base perf = %d\n" , cpu -> cpu ,
9591076 cpu -> capacity_perf , hybrid_max_perf_cpu -> capacity_perf ,
@@ -1042,6 +1159,11 @@ static void hybrid_refresh_cpu_capacity_scaling(void)
10421159 guard (mutex )(& hybrid_capacity_lock );
10431160
10441161 __hybrid_refresh_cpu_capacity_scaling ();
1162+ /*
1163+ * Perf domains are not registered before setting hybrid_max_perf_cpu,
1164+ * so register them all after setting up CPU capacity scaling.
1165+ */
1166+ hybrid_register_all_perf_domains ();
10451167}
10461168
10471169static void hybrid_init_cpu_capacity_scaling (bool refresh )
@@ -1069,7 +1191,7 @@ static void hybrid_init_cpu_capacity_scaling(bool refresh)
10691191 hybrid_refresh_cpu_capacity_scaling ();
10701192 /*
10711193 * Disabling ITMT causes sched domains to be rebuilt to disable asym
1072- * packing and enable asym capacity.
1194+ * packing and enable asym capacity and EAS .
10731195 */
10741196 sched_clear_itmt_support ();
10751197 }
@@ -1147,6 +1269,14 @@ static void hybrid_update_capacity(struct cpudata *cpu)
11471269 }
11481270
11491271 hybrid_set_cpu_capacity (cpu );
1272+ /*
1273+ * If the CPU was offline to start with and it is going online for the
1274+ * first time, a perf domain needs to be registered for it if hybrid
1275+ * capacity scaling has been enabled already. In that case, sched
1276+ * domains need to be rebuilt to take the new perf domain into account.
1277+ */
1278+ if (hybrid_register_perf_domain (cpu -> cpu ))
1279+ em_rebuild_sched_domains ();
11501280
11511281unlock :
11521282 mutex_unlock (& hybrid_capacity_lock );
@@ -2656,6 +2786,8 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
26562786 X86_MATCH (INTEL_TIGERLAKE , core_funcs ),
26572787 X86_MATCH (INTEL_SAPPHIRERAPIDS_X , core_funcs ),
26582788 X86_MATCH (INTEL_EMERALDRAPIDS_X , core_funcs ),
2789+ X86_MATCH (INTEL_GRANITERAPIDS_D , core_funcs ),
2790+ X86_MATCH (INTEL_GRANITERAPIDS_X , core_funcs ),
26592791 {}
26602792};
26612793MODULE_DEVICE_TABLE (x86cpu , intel_pstate_cpu_ids );
@@ -2672,6 +2804,7 @@ static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = {
26722804 X86_MATCH (INTEL_GRANITERAPIDS_X , core_funcs ),
26732805 X86_MATCH (INTEL_ATOM_CRESTMONT , core_funcs ),
26742806 X86_MATCH (INTEL_ATOM_CRESTMONT_X , core_funcs ),
2807+ X86_MATCH (INTEL_ATOM_DARKMONT_X , core_funcs ),
26752808 {}
26762809};
26772810#endif
@@ -3130,8 +3263,8 @@ static int intel_cpufreq_update_pstate(struct cpufreq_policy *policy,
31303263 int max_pstate = policy -> strict_target ?
31313264 target_pstate : cpu -> max_perf_ratio ;
31323265
3133- intel_cpufreq_hwp_update (cpu , target_pstate , max_pstate , 0 ,
3134- fast_switch );
3266+ intel_cpufreq_hwp_update (cpu , target_pstate , max_pstate ,
3267+ target_pstate , fast_switch );
31353268 } else if (target_pstate != old_pstate ) {
31363269 intel_cpufreq_perf_ctl_update (cpu , target_pstate , fast_switch );
31373270 }
0 commit comments