Skip to content

Commit f36de72

Browse files
committed
cpuidle: governors: teo: Adjust the classification of wakeup events
If differences between target residency values of adjacent idle states of a given CPU are relatively large, the corresponding idle state bins used by the teo governors are large either and the rule by which hits are distinguished from intercepts is inaccurate. Namely, by that rule, a wakeup event is classified as a hit if the sleep length (the time till the closest timer other than the tick) and the measured idle duration, adjusted for the entered idle state exit latency, fall into the same idle state bin. However, if that bin is large enough, the actual difference between the sleep length and the measured idle duration may be significant. It may in fact be significantly greater than the analogous difference for an event where the sleep length and the measured idle duration fall into different bins. For this reason, amend the rule in question with a check that will only allow a wakeup event to be counted as a hit if the sleep length is less than the "raw" measured idle duration (which means that the wakeup appears to have occurred after the anticipated timer event). Otherwise, the event will be counted as an intercept. Also update the documentation part explaining the difference between "hits" and "intercepts" to take the above change into account. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Christian Loehle <christian.loehle@arm.com> Link: https://patch.msgid.link/5093379.31r3eYUQgx@rafael.j.wysocki
1 parent 475ca34 commit f36de72

1 file changed

Lines changed: 14 additions & 11 deletions

File tree

  • drivers/cpuidle/governors

drivers/cpuidle/governors/teo.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@
4848
* in accordance with what happened last time.
4949
*
5050
* The "hits" metric reflects the relative frequency of situations in which the
51-
* sleep length and the idle duration measured after CPU wakeup fall into the
52-
* same bin (that is, the CPU appears to wake up "on time" relative to the sleep
53-
* length). In turn, the "intercepts" metric reflects the relative frequency of
54-
* non-timer wakeup events for which the measured idle duration falls into a bin
55-
* that corresponds to an idle state shallower than the one whose bin is fallen
56-
* into by the sleep length (these events are also referred to as "intercepts"
51+
* sleep length and the idle duration measured after CPU wakeup are close enough
52+
* (that is, the CPU appears to wake up "on time" relative to the sleep length).
53+
* In turn, the "intercepts" metric reflects the relative frequency of non-timer
54+
* wakeup events for which the measured idle duration is significantly different
55+
* from the sleep length (these events are also referred to as "intercepts"
5756
* below).
5857
*
5958
* The governor also counts "intercepts" with the measured idle duration below
@@ -167,6 +166,7 @@ static void teo_decay(unsigned int *metric)
167166
*/
168167
static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
169168
{
169+
s64 lat_ns = drv->states[dev->last_state_idx].exit_latency_ns;
170170
struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
171171
int i, idx_timer = 0, idx_duration = 0;
172172
s64 target_residency_ns, measured_ns;
@@ -182,8 +182,6 @@ static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
182182
*/
183183
measured_ns = S64_MAX;
184184
} else {
185-
s64 lat_ns = drv->states[dev->last_state_idx].exit_latency_ns;
186-
187185
measured_ns = dev->last_residency_ns;
188186
/*
189187
* The delay between the wakeup and the first instruction
@@ -253,12 +251,17 @@ static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
253251
}
254252

255253
/*
256-
* If the measured idle duration falls into the same bin as the sleep
257-
* length, this is a "hit", so update the "hits" metric for that bin.
254+
* If the measured idle duration (adjusted for the entered state exit
255+
* latency) falls into the same bin as the sleep length and the latter
256+
* is less than the "raw" measured idle duration (so the wakeup appears
257+
* to have occurred after the anticipated timer event), this is a "hit",
258+
* so update the "hits" metric for that bin.
259+
*
258260
* Otherwise, update the "intercepts" metric for the bin fallen into by
259261
* the measured idle duration.
260262
*/
261-
if (idx_timer == idx_duration) {
263+
if (idx_timer == idx_duration &&
264+
cpu_data->sleep_length_ns - measured_ns < lat_ns / 2) {
262265
cpu_data->state_bins[idx_timer].hits += PULSE;
263266
} else {
264267
cpu_data->state_bins[idx_duration].intercepts += PULSE;

0 commit comments

Comments
 (0)