Skip to content

Commit 7592019

Browse files
yu-chen-surfrafaeljw
authored andcommitted
cpufreq: governors: Fix long idle detection logic in load calculation
According to current code implementation, detecting the long idle period is done by checking if the interval between two adjacent utilization update handlers is long enough. Although this mechanism can detect if the idle period is long enough (no utilization hooks invoked during idle period), it might not cover a corner case: if the task has occupied the CPU for too long which causes no context switches during that period, then no utilization handler will be launched until this high prio task is scheduled out. As a result, the idle_periods field might be calculated incorrectly because it regards the 100% load as 0% and makes the conservative governor who uses this field confusing. Change the detection to compare the idle_time with sampling_rate directly. Reported-by: Artem S. Tashkinov <[email protected]> Signed-off-by: Chen Yu <[email protected]> Acked-by: Viresh Kumar <[email protected]> Cc: All applicable <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 41ab43c commit 7592019

File tree

1 file changed

+5
-7
lines changed

1 file changed

+5
-7
lines changed

drivers/cpufreq/cpufreq_governor.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
165165
* calls, so the previous load value can be used then.
166166
*/
167167
load = j_cdbs->prev_load;
168-
} else if (unlikely(time_elapsed > 2 * sampling_rate &&
168+
} else if (unlikely((int)idle_time > 2 * sampling_rate &&
169169
j_cdbs->prev_load)) {
170170
/*
171171
* If the CPU had gone completely idle and a task has
@@ -185,10 +185,8 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
185185
* clear prev_load to guarantee that the load will be
186186
* computed again next time.
187187
*
188-
* Detecting this situation is easy: the governor's
189-
* utilization update handler would not have run during
190-
* CPU-idle periods. Hence, an unusually large
191-
* 'time_elapsed' (as compared to the sampling rate)
188+
* Detecting this situation is easy: an unusually large
189+
* 'idle_time' (as compared to the sampling rate)
192190
* indicates this scenario.
193191
*/
194192
load = j_cdbs->prev_load;
@@ -217,8 +215,8 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
217215
j_cdbs->prev_load = load;
218216
}
219217

220-
if (time_elapsed > 2 * sampling_rate) {
221-
unsigned int periods = time_elapsed / sampling_rate;
218+
if (unlikely((int)idle_time > 2 * sampling_rate)) {
219+
unsigned int periods = idle_time / sampling_rate;
222220

223221
if (periods < idle_periods)
224222
idle_periods = periods;

0 commit comments

Comments
 (0)