aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_governor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq_governor.c')
-rw-r--r--drivers/cpufreq/cpufreq_governor.c67
1 files changed, 64 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index e1c6433b16e0..1b44496b2d2b 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -36,14 +36,29 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
36 struct od_dbs_tuners *od_tuners = dbs_data->tuners; 36 struct od_dbs_tuners *od_tuners = dbs_data->tuners;
37 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; 37 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
38 struct cpufreq_policy *policy; 38 struct cpufreq_policy *policy;
39 unsigned int sampling_rate;
39 unsigned int max_load = 0; 40 unsigned int max_load = 0;
40 unsigned int ignore_nice; 41 unsigned int ignore_nice;
41 unsigned int j; 42 unsigned int j;
42 43
43 if (dbs_data->cdata->governor == GOV_ONDEMAND) 44 if (dbs_data->cdata->governor == GOV_ONDEMAND) {
45 struct od_cpu_dbs_info_s *od_dbs_info =
46 dbs_data->cdata->get_cpu_dbs_info_s(cpu);
47
48 /*
49 * Sometimes, the ondemand governor uses an additional
50 * multiplier to give long delays. So apply this multiplier to
51 * the 'sampling_rate', so as to keep the wake-up-from-idle
52 * detection logic a bit conservative.
53 */
54 sampling_rate = od_tuners->sampling_rate;
55 sampling_rate *= od_dbs_info->rate_mult;
56
44 ignore_nice = od_tuners->ignore_nice_load; 57 ignore_nice = od_tuners->ignore_nice_load;
45 else 58 } else {
59 sampling_rate = cs_tuners->sampling_rate;
46 ignore_nice = cs_tuners->ignore_nice_load; 60 ignore_nice = cs_tuners->ignore_nice_load;
61 }
47 62
48 policy = cdbs->cur_policy; 63 policy = cdbs->cur_policy;
49 64
@@ -96,7 +111,46 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
96 if (unlikely(!wall_time || wall_time < idle_time)) 111 if (unlikely(!wall_time || wall_time < idle_time))
97 continue; 112 continue;
98 113
99 load = 100 * (wall_time - idle_time) / wall_time; 114 /*
115 * If the CPU had gone completely idle, and a task just woke up
116 * on this CPU now, it would be unfair to calculate 'load' the
117 * usual way for this elapsed time-window, because it will show
118 * near-zero load, irrespective of how CPU intensive that task
119 * actually is. This is undesirable for latency-sensitive bursty
120 * workloads.
121 *
122 * To avoid this, we reuse the 'load' from the previous
123 * time-window and give this task a chance to start with a
124 * reasonably high CPU frequency. (However, we shouldn't over-do
125 * this copy, lest we get stuck at a high load (high frequency)
126 * for too long, even when the current system load has actually
127 * dropped down. So we perform the copy only once, upon the
128 * first wake-up from idle.)
129 *
130 * Detecting this situation is easy: the governor's deferrable
131 * timer would not have fired during CPU-idle periods. Hence
132 * an unusually large 'wall_time' (as compared to the sampling
133 * rate) indicates this scenario.
134 *
135 * prev_load can be zero in two cases and we must recalculate it
136 * for both cases:
137 * - during long idle intervals
138 * - explicitly set to zero
139 */
140 if (unlikely(wall_time > (2 * sampling_rate) &&
141 j_cdbs->prev_load)) {
142 load = j_cdbs->prev_load;
143
144 /*
145 * Perform a destructive copy, to ensure that we copy
146 * the previous load only once, upon the first wake-up
147 * from idle.
148 */
149 j_cdbs->prev_load = 0;
150 } else {
151 load = 100 * (wall_time - idle_time) / wall_time;
152 j_cdbs->prev_load = load;
153 }
100 154
101 if (load > max_load) 155 if (load > max_load)
102 max_load = load; 156 max_load = load;
@@ -318,11 +372,18 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
318 for_each_cpu(j, policy->cpus) { 372 for_each_cpu(j, policy->cpus) {
319 struct cpu_dbs_common_info *j_cdbs = 373 struct cpu_dbs_common_info *j_cdbs =
320 dbs_data->cdata->get_cpu_cdbs(j); 374 dbs_data->cdata->get_cpu_cdbs(j);
375 unsigned int prev_load;
321 376
322 j_cdbs->cpu = j; 377 j_cdbs->cpu = j;
323 j_cdbs->cur_policy = policy; 378 j_cdbs->cur_policy = policy;
324 j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, 379 j_cdbs->prev_cpu_idle = get_cpu_idle_time(j,
325 &j_cdbs->prev_cpu_wall, io_busy); 380 &j_cdbs->prev_cpu_wall, io_busy);
381
382 prev_load = (unsigned int)
383 (j_cdbs->prev_cpu_wall - j_cdbs->prev_cpu_idle);
384 j_cdbs->prev_load = 100 * prev_load /
385 (unsigned int) j_cdbs->prev_cpu_wall;
386
326 if (ignore_nice) 387 if (ignore_nice)
327 j_cdbs->prev_cpu_nice = 388 j_cdbs->prev_cpu_nice =
328 kcpustat_cpu(j).cpustat[CPUTIME_NICE]; 389 kcpustat_cpu(j).cpustat[CPUTIME_NICE];