54
54
* shallower than the one whose bin is fallen into by the sleep length (these
55
55
* situations are referred to as "intercepts" below).
56
56
*
57
- * In addition to the metrics described above, the governor counts recent
58
- * intercepts (that is, intercepts that have occurred during the last
59
- * %NR_RECENT invocations of it for the given CPU) for each bin.
60
- *
61
57
* In order to select an idle state for a CPU, the governor takes the following
62
58
* steps (modulo the possible latency constraint that must be taken into account
63
59
* too):
64
60
*
65
61
* 1. Find the deepest CPU idle state whose target residency does not exceed
66
- * the current sleep length (the candidate idle state) and compute 3 sums as
62
+ * the current sleep length (the candidate idle state) and compute 2 sums as
67
63
* follows:
68
64
*
69
65
* - The sum of the "hits" and "intercepts" metrics for the candidate state
76
72
* idle long enough to avoid being intercepted if the sleep length had been
77
73
* equal to the current one).
78
74
*
79
- * - The sum of the numbers of recent intercepts for all of the idle states
80
- * shallower than the candidate one.
81
- *
82
- * 2. If the second sum is greater than the first one or the third sum is
83
- * greater than %NR_RECENT / 2, the CPU is likely to wake up early, so look
84
- * for an alternative idle state to select.
75
+ * 2. If the second sum is greater than the first one the CPU is likely to wake
76
+ * up early, so look for an alternative idle state to select.
85
77
*
86
78
* - Traverse the idle states shallower than the candidate one in the
87
79
* descending order.
88
80
*
89
- * - For each of them compute the sum of the "intercepts" metrics and the sum
90
- * of the numbers of recent intercepts over all of the idle states between
91
- * it and the candidate one (including the former and excluding the
92
- * latter).
81
+ * - For each of them compute the sum of the "intercepts" metrics over all
82
+ * of the idle states between it and the candidate one (including the
83
+ * former and excluding the latter).
93
84
*
94
85
* - If each of these sums that needs to be taken into account (because the
95
86
* check related to it has indicated that the CPU is likely to wake up
116
107
#define PULSE 1024
117
108
#define DECAY_SHIFT 3
118
109
119
- /*
120
- * Number of the most recent idle duration values to take into consideration for
121
- * the detection of recent early wakeup patterns.
122
- */
123
- #define NR_RECENT 9
124
-
125
110
/**
126
111
* struct teo_bin - Metrics used by the TEO cpuidle governor.
127
112
* @intercepts: The "intercepts" metric.
128
113
* @hits: The "hits" metric.
129
- * @recent: The number of recent "intercepts".
130
114
*/
131
115
struct teo_bin {
132
116
unsigned int intercepts ;
133
117
unsigned int hits ;
134
- unsigned int recent ;
135
118
};
136
119
137
120
/**
@@ -140,17 +123,13 @@ struct teo_bin {
140
123
* @sleep_length_ns: Time till the closest timer event (at the selection time).
141
124
* @state_bins: Idle state data bins for this CPU.
142
125
* @total: Grand total of the "intercepts" and "hits" metrics for all bins.
143
- * @next_recent_idx: Index of the next @recent_idx entry to update.
144
- * @recent_idx: Indices of bins corresponding to recent "intercepts".
145
126
* @tick_hits: Number of "hits" after TICK_NSEC.
146
127
*/
147
128
struct teo_cpu {
148
129
s64 time_span_ns ;
149
130
s64 sleep_length_ns ;
150
131
struct teo_bin state_bins [CPUIDLE_STATE_MAX ];
151
132
unsigned int total ;
152
- int next_recent_idx ;
153
- int recent_idx [NR_RECENT ];
154
133
unsigned int tick_hits ;
155
134
};
156
135
@@ -222,13 +201,6 @@ static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
222
201
}
223
202
}
224
203
225
- i = cpu_data -> next_recent_idx ++ ;
226
- if (cpu_data -> next_recent_idx >= NR_RECENT )
227
- cpu_data -> next_recent_idx = 0 ;
228
-
229
- if (cpu_data -> recent_idx [i ] >= 0 )
230
- cpu_data -> state_bins [cpu_data -> recent_idx [i ]].recent -- ;
231
-
232
204
/*
233
205
* If the deepest state's target residency is below the tick length,
234
206
* make a record of it to help teo_select() decide whether or not
@@ -255,14 +227,10 @@ static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
255
227
* Otherwise, update the "intercepts" metric for the bin fallen into by
256
228
* the measured idle duration.
257
229
*/
258
- if (idx_timer == idx_duration ) {
230
+ if (idx_timer == idx_duration )
259
231
cpu_data -> state_bins [idx_timer ].hits += PULSE ;
260
- cpu_data -> recent_idx [i ] = -1 ;
261
- } else {
232
+ else
262
233
cpu_data -> state_bins [idx_duration ].intercepts += PULSE ;
263
- cpu_data -> state_bins [idx_duration ].recent ++ ;
264
- cpu_data -> recent_idx [i ] = idx_duration ;
265
- }
266
234
267
235
end :
268
236
cpu_data -> total += PULSE ;
@@ -315,13 +283,10 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
315
283
unsigned int tick_intercept_sum = 0 ;
316
284
unsigned int idx_intercept_sum = 0 ;
317
285
unsigned int intercept_sum = 0 ;
318
- unsigned int idx_recent_sum = 0 ;
319
- unsigned int recent_sum = 0 ;
320
286
unsigned int idx_hit_sum = 0 ;
321
287
unsigned int hit_sum = 0 ;
322
288
int constraint_idx = 0 ;
323
289
int idx0 = 0 , idx = -1 ;
324
- bool alt_intercepts , alt_recent ;
325
290
s64 duration_ns ;
326
291
int i ;
327
292
@@ -357,7 +322,6 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
357
322
*/
358
323
intercept_sum += prev_bin -> intercepts ;
359
324
hit_sum += prev_bin -> hits ;
360
- recent_sum += prev_bin -> recent ;
361
325
362
326
if (dev -> states_usage [i ].disable )
363
327
continue ;
@@ -373,7 +337,6 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
373
337
/* Save the sums for the current state. */
374
338
idx_intercept_sum = intercept_sum ;
375
339
idx_hit_sum = hit_sum ;
376
- idx_recent_sum = recent_sum ;
377
340
}
378
341
379
342
/* Avoid unnecessary overhead. */
@@ -398,37 +361,28 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
398
361
* If the sum of the intercepts metric for all of the idle states
399
362
* shallower than the current candidate one (idx) is greater than the
400
363
* sum of the intercepts and hits metrics for the candidate state and
401
- * all of the deeper states, or the sum of the numbers of recent
402
- * intercepts over all of the states shallower than the candidate one
403
- * is greater than a half of the number of recent events taken into
404
- * account, a shallower idle state is likely to be a better choice.
364
+ * all of the deeper states a shallower idle state is likely to be a
365
+ * better choice.
405
366
*/
406
- alt_intercepts = 2 * idx_intercept_sum > cpu_data -> total - idx_hit_sum ;
407
- alt_recent = idx_recent_sum > NR_RECENT / 2 ;
408
- if (alt_recent || alt_intercepts ) {
367
+ if (2 * idx_intercept_sum > cpu_data -> total - idx_hit_sum ) {
409
368
int first_suitable_idx = idx ;
410
369
411
370
/*
412
371
* Look for the deepest idle state whose target residency had
413
372
* not exceeded the idle duration in over a half of the relevant
414
- * cases (both with respect to intercepts overall and with
415
- * respect to the recent intercepts only) in the past.
373
+ * cases in the past.
416
374
*
417
375
* Take the possible duration limitation present if the tick
418
376
* has been stopped already into account.
419
377
*/
420
378
intercept_sum = 0 ;
421
- recent_sum = 0 ;
422
379
423
380
for (i = idx - 1 ; i >= 0 ; i -- ) {
424
381
struct teo_bin * bin = & cpu_data -> state_bins [i ];
425
382
426
383
intercept_sum += bin -> intercepts ;
427
- recent_sum += bin -> recent ;
428
384
429
- if ((!alt_recent || 2 * recent_sum > idx_recent_sum ) &&
430
- (!alt_intercepts ||
431
- 2 * intercept_sum > idx_intercept_sum )) {
385
+ if (2 * intercept_sum > idx_intercept_sum ) {
432
386
/*
433
387
* Use the current state unless it is too
434
388
* shallow or disabled, in which case take the
@@ -564,13 +518,9 @@ static int teo_enable_device(struct cpuidle_driver *drv,
564
518
struct cpuidle_device * dev )
565
519
{
566
520
struct teo_cpu * cpu_data = per_cpu_ptr (& teo_cpus , dev -> cpu );
567
- int i ;
568
521
569
522
memset (cpu_data , 0 , sizeof (* cpu_data ));
570
523
571
- for (i = 0 ; i < NR_RECENT ; i ++ )
572
- cpu_data -> recent_idx [i ] = -1 ;
573
-
574
524
return 0 ;
575
525
}
576
526
0 commit comments