diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq_governor.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 67 |
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]; |