@@ -910,7 +910,14 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time)
910
910
cpu -> prev_aperf = aperf ;
911
911
cpu -> prev_mperf = mperf ;
912
912
cpu -> prev_tsc = tsc ;
913
- return true;
913
+ /*
914
+ * First time this function is invoked in a given cycle, all of the
915
+ * previous sample data fields are equal to zero or stale and they must
916
+ * be populated with meaningful numbers for things to work, so assume
917
+ * that sample.time will always be reset before setting the utilization
918
+ * update hook and make the caller skip the sample then.
919
+ */
920
+ return !!cpu -> last_sample_time ;
914
921
}
915
922
916
923
static inline int32_t get_avg_frequency (struct cpudata * cpu )
@@ -984,8 +991,7 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
984
991
* enough period of time to adjust our busyness.
985
992
*/
986
993
duration_ns = cpu -> sample .time - cpu -> last_sample_time ;
987
- if ((s64 )duration_ns > pid_params .sample_rate_ns * 3
988
- && cpu -> last_sample_time > 0 ) {
994
+ if ((s64 )duration_ns > pid_params .sample_rate_ns * 3 ) {
989
995
sample_ratio = div_fp (int_tofp (pid_params .sample_rate_ns ),
990
996
int_tofp (duration_ns ));
991
997
core_busy = mul_fp (core_busy , sample_ratio );
@@ -1100,10 +1106,8 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
1100
1106
intel_pstate_get_cpu_pstates (cpu );
1101
1107
1102
1108
intel_pstate_busy_pid_reset (cpu );
1103
- intel_pstate_sample (cpu , 0 );
1104
1109
1105
1110
cpu -> update_util .func = intel_pstate_update_util ;
1106
- cpufreq_set_update_util_data (cpunum , & cpu -> update_util );
1107
1111
1108
1112
pr_debug ("intel_pstate: controlling: cpu %d\n" , cpunum );
1109
1113
@@ -1122,18 +1126,33 @@ static unsigned int intel_pstate_get(unsigned int cpu_num)
1122
1126
return get_avg_frequency (cpu );
1123
1127
}
1124
1128
1129
+ static void intel_pstate_set_update_util_hook (unsigned int cpu_num )
1130
+ {
1131
+ struct cpudata * cpu = all_cpu_data [cpu_num ];
1132
+
1133
+ /* Prevent intel_pstate_update_util() from using stale data. */
1134
+ cpu -> sample .time = 0 ;
1135
+ cpufreq_set_update_util_data (cpu_num , & cpu -> update_util );
1136
+ }
1137
+
1138
+ static void intel_pstate_clear_update_util_hook (unsigned int cpu )
1139
+ {
1140
+ cpufreq_set_update_util_data (cpu , NULL );
1141
+ synchronize_sched ();
1142
+ }
1143
+
1125
1144
static int intel_pstate_set_policy (struct cpufreq_policy * policy )
1126
1145
{
1127
1146
if (!policy -> cpuinfo .max_freq )
1128
1147
return - ENODEV ;
1129
1148
1149
+ intel_pstate_clear_update_util_hook (policy -> cpu );
1150
+
1130
1151
if (policy -> policy == CPUFREQ_POLICY_PERFORMANCE &&
1131
1152
policy -> max >= policy -> cpuinfo .max_freq ) {
1132
1153
pr_debug ("intel_pstate: set performance\n" );
1133
1154
limits = & performance_limits ;
1134
- if (hwp_active )
1135
- intel_pstate_hwp_set (policy -> cpus );
1136
- return 0 ;
1155
+ goto out ;
1137
1156
}
1138
1157
1139
1158
pr_debug ("intel_pstate: set powersave\n" );
@@ -1163,6 +1182,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1163
1182
limits -> max_perf = div_fp (int_tofp (limits -> max_perf_pct ),
1164
1183
int_tofp (100 ));
1165
1184
1185
+ out :
1186
+ intel_pstate_set_update_util_hook (policy -> cpu );
1187
+
1166
1188
if (hwp_active )
1167
1189
intel_pstate_hwp_set (policy -> cpus );
1168
1190
@@ -1187,8 +1209,7 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
1187
1209
1188
1210
pr_debug ("intel_pstate: CPU %d exiting\n" , cpu_num );
1189
1211
1190
- cpufreq_set_update_util_data (cpu_num , NULL );
1191
- synchronize_sched ();
1212
+ intel_pstate_clear_update_util_hook (cpu_num );
1192
1213
1193
1214
if (hwp_active )
1194
1215
return ;
@@ -1455,8 +1476,7 @@ static int __init intel_pstate_init(void)
1455
1476
get_online_cpus ();
1456
1477
for_each_online_cpu (cpu ) {
1457
1478
if (all_cpu_data [cpu ]) {
1458
- cpufreq_set_update_util_data (cpu , NULL );
1459
- synchronize_sched ();
1479
+ intel_pstate_clear_update_util_hook (cpu );
1460
1480
kfree (all_cpu_data [cpu ]);
1461
1481
}
1462
1482
}
0 commit comments