diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq_governor.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 48 |
1 files changed, 18 insertions, 30 deletions
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 326f0c2e2bd5..443442df113b 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
@@ -67,13 +67,13 @@ static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) | |||
67 | return cputime_to_usecs(idle_time); | 67 | return cputime_to_usecs(idle_time); |
68 | } | 68 | } |
69 | 69 | ||
70 | u64 get_cpu_idle_time(unsigned int cpu, u64 *wall) | 70 | u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy) |
71 | { | 71 | { |
72 | u64 idle_time = get_cpu_idle_time_us(cpu, NULL); | 72 | u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL); |
73 | 73 | ||
74 | if (idle_time == -1ULL) | 74 | if (idle_time == -1ULL) |
75 | return get_cpu_idle_time_jiffy(cpu, wall); | 75 | return get_cpu_idle_time_jiffy(cpu, wall); |
76 | else | 76 | else if (!io_busy) |
77 | idle_time += get_cpu_iowait_time_us(cpu, wall); | 77 | idle_time += get_cpu_iowait_time_us(cpu, wall); |
78 | 78 | ||
79 | return idle_time; | 79 | return idle_time; |
@@ -100,13 +100,22 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) | |||
100 | /* Get Absolute Load (in terms of freq for ondemand gov) */ | 100 | /* Get Absolute Load (in terms of freq for ondemand gov) */ |
101 | for_each_cpu(j, policy->cpus) { | 101 | for_each_cpu(j, policy->cpus) { |
102 | struct cpu_dbs_common_info *j_cdbs; | 102 | struct cpu_dbs_common_info *j_cdbs; |
103 | u64 cur_wall_time, cur_idle_time, cur_iowait_time; | 103 | u64 cur_wall_time, cur_idle_time; |
104 | unsigned int idle_time, wall_time, iowait_time; | 104 | unsigned int idle_time, wall_time; |
105 | unsigned int load; | 105 | unsigned int load; |
106 | int io_busy = 0; | ||
106 | 107 | ||
107 | j_cdbs = dbs_data->cdata->get_cpu_cdbs(j); | 108 | j_cdbs = dbs_data->cdata->get_cpu_cdbs(j); |
108 | 109 | ||
109 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); | 110 | /* |
111 | * For the purpose of ondemand, waiting for disk IO is | ||
112 | * an indication that you're performance critical, and | ||
113 | * not that the system is actually idle. So do not add | ||
114 | * the iowait time to the cpu idle time. | ||
115 | */ | ||
116 | if (dbs_data->cdata->governor == GOV_ONDEMAND) | ||
117 | io_busy = od_tuners->io_is_busy; | ||
118 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time, io_busy); | ||
110 | 119 | ||
111 | wall_time = (unsigned int) | 120 | wall_time = (unsigned int) |
112 | (cur_wall_time - j_cdbs->prev_cpu_wall); | 121 | (cur_wall_time - j_cdbs->prev_cpu_wall); |
@@ -134,29 +143,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) | |||
134 | idle_time += jiffies_to_usecs(cur_nice_jiffies); | 143 | idle_time += jiffies_to_usecs(cur_nice_jiffies); |
135 | } | 144 | } |
136 | 145 | ||
137 | if (dbs_data->cdata->governor == GOV_ONDEMAND) { | ||
138 | struct od_cpu_dbs_info_s *od_j_dbs_info = | ||
139 | dbs_data->cdata->get_cpu_dbs_info_s(cpu); | ||
140 | |||
141 | cur_iowait_time = get_cpu_iowait_time_us(j, | ||
142 | &cur_wall_time); | ||
143 | if (cur_iowait_time == -1ULL) | ||
144 | cur_iowait_time = 0; | ||
145 | |||
146 | iowait_time = (unsigned int) (cur_iowait_time - | ||
147 | od_j_dbs_info->prev_cpu_iowait); | ||
148 | od_j_dbs_info->prev_cpu_iowait = cur_iowait_time; | ||
149 | |||
150 | /* | ||
151 | * For the purpose of ondemand, waiting for disk IO is | ||
152 | * an indication that you're performance critical, and | ||
153 | * not that the system is actually idle. So subtract the | ||
154 | * iowait time from the cpu idle time. | ||
155 | */ | ||
156 | if (od_tuners->io_is_busy && idle_time >= iowait_time) | ||
157 | idle_time -= iowait_time; | ||
158 | } | ||
159 | |||
160 | if (unlikely(!wall_time || wall_time < idle_time)) | 146 | if (unlikely(!wall_time || wall_time < idle_time)) |
161 | continue; | 147 | continue; |
162 | 148 | ||
@@ -254,6 +240,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
254 | struct cs_dbs_tuners *cs_tuners = NULL; | 240 | struct cs_dbs_tuners *cs_tuners = NULL; |
255 | struct cpu_dbs_common_info *cpu_cdbs; | 241 | struct cpu_dbs_common_info *cpu_cdbs; |
256 | unsigned int sampling_rate, latency, ignore_nice, j, cpu = policy->cpu; | 242 | unsigned int sampling_rate, latency, ignore_nice, j, cpu = policy->cpu; |
243 | int io_busy = 0; | ||
257 | int rc; | 244 | int rc; |
258 | 245 | ||
259 | if (have_governor_per_policy()) | 246 | if (have_governor_per_policy()) |
@@ -353,6 +340,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
353 | sampling_rate = od_tuners->sampling_rate; | 340 | sampling_rate = od_tuners->sampling_rate; |
354 | ignore_nice = od_tuners->ignore_nice; | 341 | ignore_nice = od_tuners->ignore_nice; |
355 | od_ops = dbs_data->cdata->gov_ops; | 342 | od_ops = dbs_data->cdata->gov_ops; |
343 | io_busy = od_tuners->io_is_busy; | ||
356 | } | 344 | } |
357 | 345 | ||
358 | switch (event) { | 346 | switch (event) { |
@@ -369,7 +357,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
369 | j_cdbs->cpu = j; | 357 | j_cdbs->cpu = j; |
370 | j_cdbs->cur_policy = policy; | 358 | j_cdbs->cur_policy = policy; |
371 | j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, | 359 | j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, |
372 | &j_cdbs->prev_cpu_wall); | 360 | &j_cdbs->prev_cpu_wall, io_busy); |
373 | if (ignore_nice) | 361 | if (ignore_nice) |
374 | j_cdbs->prev_cpu_nice = | 362 | j_cdbs->prev_cpu_nice = |
375 | kcpustat_cpu(j).cpustat[CPUTIME_NICE]; | 363 | kcpustat_cpu(j).cpustat[CPUTIME_NICE]; |