diff options
Diffstat (limited to 'drivers/cpufreq')
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 19 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 75 |
3 files changed, 93 insertions, 9 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2d5d575e889d..75d293eeb3ee 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -1113,6 +1113,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
| 1113 | unsigned int cpu = sys_dev->id; | 1113 | unsigned int cpu = sys_dev->id; |
| 1114 | unsigned long flags; | 1114 | unsigned long flags; |
| 1115 | struct cpufreq_policy *data; | 1115 | struct cpufreq_policy *data; |
| 1116 | struct kobject *kobj; | ||
| 1117 | struct completion *cmp; | ||
| 1116 | #ifdef CONFIG_SMP | 1118 | #ifdef CONFIG_SMP |
| 1117 | struct sys_device *cpu_sys_dev; | 1119 | struct sys_device *cpu_sys_dev; |
| 1118 | unsigned int j; | 1120 | unsigned int j; |
| @@ -1141,10 +1143,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
| 1141 | dprintk("removing link\n"); | 1143 | dprintk("removing link\n"); |
| 1142 | cpumask_clear_cpu(cpu, data->cpus); | 1144 | cpumask_clear_cpu(cpu, data->cpus); |
| 1143 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1145 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
| 1144 | sysfs_remove_link(&sys_dev->kobj, "cpufreq"); | 1146 | kobj = &sys_dev->kobj; |
| 1145 | cpufreq_cpu_put(data); | 1147 | cpufreq_cpu_put(data); |
| 1146 | cpufreq_debug_enable_ratelimit(); | 1148 | cpufreq_debug_enable_ratelimit(); |
| 1147 | unlock_policy_rwsem_write(cpu); | 1149 | unlock_policy_rwsem_write(cpu); |
| 1150 | sysfs_remove_link(kobj, "cpufreq"); | ||
| 1148 | return 0; | 1151 | return 0; |
| 1149 | } | 1152 | } |
| 1150 | #endif | 1153 | #endif |
| @@ -1181,7 +1184,10 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
| 1181 | data->governor->name, CPUFREQ_NAME_LEN); | 1184 | data->governor->name, CPUFREQ_NAME_LEN); |
| 1182 | #endif | 1185 | #endif |
| 1183 | cpu_sys_dev = get_cpu_sysdev(j); | 1186 | cpu_sys_dev = get_cpu_sysdev(j); |
| 1184 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); | 1187 | kobj = &cpu_sys_dev->kobj; |
| 1188 | unlock_policy_rwsem_write(cpu); | ||
| 1189 | sysfs_remove_link(kobj, "cpufreq"); | ||
| 1190 | lock_policy_rwsem_write(cpu); | ||
| 1185 | cpufreq_cpu_put(data); | 1191 | cpufreq_cpu_put(data); |
| 1186 | } | 1192 | } |
| 1187 | } | 1193 | } |
| @@ -1192,19 +1198,22 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
| 1192 | if (cpufreq_driver->target) | 1198 | if (cpufreq_driver->target) |
| 1193 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1199 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); |
| 1194 | 1200 | ||
| 1195 | kobject_put(&data->kobj); | 1201 | kobj = &data->kobj; |
| 1202 | cmp = &data->kobj_unregister; | ||
| 1203 | unlock_policy_rwsem_write(cpu); | ||
| 1204 | kobject_put(kobj); | ||
| 1196 | 1205 | ||
| 1197 | /* we need to make sure that the underlying kobj is actually | 1206 | /* we need to make sure that the underlying kobj is actually |
| 1198 | * not referenced anymore by anybody before we proceed with | 1207 | * not referenced anymore by anybody before we proceed with |
| 1199 | * unloading. | 1208 | * unloading. |
| 1200 | */ | 1209 | */ |
| 1201 | dprintk("waiting for dropping of refcount\n"); | 1210 | dprintk("waiting for dropping of refcount\n"); |
| 1202 | wait_for_completion(&data->kobj_unregister); | 1211 | wait_for_completion(cmp); |
| 1203 | dprintk("wait complete\n"); | 1212 | dprintk("wait complete\n"); |
| 1204 | 1213 | ||
| 1214 | lock_policy_rwsem_write(cpu); | ||
| 1205 | if (cpufreq_driver->exit) | 1215 | if (cpufreq_driver->exit) |
| 1206 | cpufreq_driver->exit(data); | 1216 | cpufreq_driver->exit(data); |
| 1207 | |||
| 1208 | unlock_policy_rwsem_write(cpu); | 1217 | unlock_policy_rwsem_write(cpu); |
| 1209 | 1218 | ||
| 1210 | free_cpumask_var(data->related_cpus); | 1219 | free_cpumask_var(data->related_cpus); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 599a40b25cb0..3a147874a465 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
| @@ -444,6 +444,7 @@ static struct attribute_group dbs_attr_group_old = { | |||
| 444 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | 444 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
| 445 | { | 445 | { |
| 446 | unsigned int load = 0; | 446 | unsigned int load = 0; |
| 447 | unsigned int max_load = 0; | ||
| 447 | unsigned int freq_target; | 448 | unsigned int freq_target; |
| 448 | 449 | ||
| 449 | struct cpufreq_policy *policy; | 450 | struct cpufreq_policy *policy; |
| @@ -501,6 +502,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 501 | continue; | 502 | continue; |
| 502 | 503 | ||
| 503 | load = 100 * (wall_time - idle_time) / wall_time; | 504 | load = 100 * (wall_time - idle_time) / wall_time; |
| 505 | |||
| 506 | if (load > max_load) | ||
| 507 | max_load = load; | ||
| 504 | } | 508 | } |
| 505 | 509 | ||
| 506 | /* | 510 | /* |
| @@ -511,7 +515,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 511 | return; | 515 | return; |
| 512 | 516 | ||
| 513 | /* Check for frequency increase */ | 517 | /* Check for frequency increase */ |
| 514 | if (load > dbs_tuners_ins.up_threshold) { | 518 | if (max_load > dbs_tuners_ins.up_threshold) { |
| 515 | this_dbs_info->down_skip = 0; | 519 | this_dbs_info->down_skip = 0; |
| 516 | 520 | ||
| 517 | /* if we are already at full speed then break out early */ | 521 | /* if we are already at full speed then break out early */ |
| @@ -538,7 +542,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 538 | * can support the current CPU usage without triggering the up | 542 | * can support the current CPU usage without triggering the up |
| 539 | * policy. To be safe, we focus 10 points under the threshold. | 543 | * policy. To be safe, we focus 10 points under the threshold. |
| 540 | */ | 544 | */ |
| 541 | if (load < (dbs_tuners_ins.down_threshold - 10)) { | 545 | if (max_load < (dbs_tuners_ins.down_threshold - 10)) { |
| 542 | freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100; | 546 | freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100; |
| 543 | 547 | ||
| 544 | this_dbs_info->requested_freq -= freq_target; | 548 | this_dbs_info->requested_freq -= freq_target; |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index bd444dc93cf2..8e9dbdc6c700 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
| @@ -73,6 +73,7 @@ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; | |||
| 73 | 73 | ||
| 74 | struct cpu_dbs_info_s { | 74 | struct cpu_dbs_info_s { |
| 75 | cputime64_t prev_cpu_idle; | 75 | cputime64_t prev_cpu_idle; |
| 76 | cputime64_t prev_cpu_iowait; | ||
| 76 | cputime64_t prev_cpu_wall; | 77 | cputime64_t prev_cpu_wall; |
| 77 | cputime64_t prev_cpu_nice; | 78 | cputime64_t prev_cpu_nice; |
| 78 | struct cpufreq_policy *cur_policy; | 79 | struct cpufreq_policy *cur_policy; |
| @@ -108,6 +109,7 @@ static struct dbs_tuners { | |||
| 108 | unsigned int down_differential; | 109 | unsigned int down_differential; |
| 109 | unsigned int ignore_nice; | 110 | unsigned int ignore_nice; |
| 110 | unsigned int powersave_bias; | 111 | unsigned int powersave_bias; |
| 112 | unsigned int io_is_busy; | ||
| 111 | } dbs_tuners_ins = { | 113 | } dbs_tuners_ins = { |
| 112 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 114 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
| 113 | .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL, | 115 | .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL, |
| @@ -148,6 +150,16 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | |||
| 148 | return idle_time; | 150 | return idle_time; |
| 149 | } | 151 | } |
| 150 | 152 | ||
| 153 | static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall) | ||
| 154 | { | ||
| 155 | u64 iowait_time = get_cpu_iowait_time_us(cpu, wall); | ||
| 156 | |||
| 157 | if (iowait_time == -1ULL) | ||
| 158 | return 0; | ||
| 159 | |||
| 160 | return iowait_time; | ||
| 161 | } | ||
| 162 | |||
| 151 | /* | 163 | /* |
| 152 | * Find right freq to be set now with powersave_bias on. | 164 | * Find right freq to be set now with powersave_bias on. |
| 153 | * Returns the freq_hi to be used right now and will set freq_hi_jiffies, | 165 | * Returns the freq_hi to be used right now and will set freq_hi_jiffies, |
| @@ -249,6 +261,7 @@ static ssize_t show_##file_name \ | |||
| 249 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 261 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ |
| 250 | } | 262 | } |
| 251 | show_one(sampling_rate, sampling_rate); | 263 | show_one(sampling_rate, sampling_rate); |
| 264 | show_one(io_is_busy, io_is_busy); | ||
| 252 | show_one(up_threshold, up_threshold); | 265 | show_one(up_threshold, up_threshold); |
| 253 | show_one(ignore_nice_load, ignore_nice); | 266 | show_one(ignore_nice_load, ignore_nice); |
| 254 | show_one(powersave_bias, powersave_bias); | 267 | show_one(powersave_bias, powersave_bias); |
| @@ -299,6 +312,23 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, | |||
| 299 | return count; | 312 | return count; |
| 300 | } | 313 | } |
| 301 | 314 | ||
| 315 | static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, | ||
| 316 | const char *buf, size_t count) | ||
| 317 | { | ||
| 318 | unsigned int input; | ||
| 319 | int ret; | ||
| 320 | |||
| 321 | ret = sscanf(buf, "%u", &input); | ||
| 322 | if (ret != 1) | ||
| 323 | return -EINVAL; | ||
| 324 | |||
| 325 | mutex_lock(&dbs_mutex); | ||
| 326 | dbs_tuners_ins.io_is_busy = !!input; | ||
| 327 | mutex_unlock(&dbs_mutex); | ||
| 328 | |||
| 329 | return count; | ||
| 330 | } | ||
| 331 | |||
| 302 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, | 332 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, |
| 303 | const char *buf, size_t count) | 333 | const char *buf, size_t count) |
| 304 | { | 334 | { |
| @@ -381,6 +411,7 @@ static struct global_attr _name = \ | |||
| 381 | __ATTR(_name, 0644, show_##_name, store_##_name) | 411 | __ATTR(_name, 0644, show_##_name, store_##_name) |
| 382 | 412 | ||
| 383 | define_one_rw(sampling_rate); | 413 | define_one_rw(sampling_rate); |
| 414 | define_one_rw(io_is_busy); | ||
| 384 | define_one_rw(up_threshold); | 415 | define_one_rw(up_threshold); |
| 385 | define_one_rw(ignore_nice_load); | 416 | define_one_rw(ignore_nice_load); |
| 386 | define_one_rw(powersave_bias); | 417 | define_one_rw(powersave_bias); |
| @@ -392,6 +423,7 @@ static struct attribute *dbs_attributes[] = { | |||
| 392 | &up_threshold.attr, | 423 | &up_threshold.attr, |
| 393 | &ignore_nice_load.attr, | 424 | &ignore_nice_load.attr, |
| 394 | &powersave_bias.attr, | 425 | &powersave_bias.attr, |
| 426 | &io_is_busy.attr, | ||
| 395 | NULL | 427 | NULL |
| 396 | }; | 428 | }; |
| 397 | 429 | ||
| @@ -470,14 +502,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 470 | 502 | ||
| 471 | for_each_cpu(j, policy->cpus) { | 503 | for_each_cpu(j, policy->cpus) { |
| 472 | struct cpu_dbs_info_s *j_dbs_info; | 504 | struct cpu_dbs_info_s *j_dbs_info; |
| 473 | cputime64_t cur_wall_time, cur_idle_time; | 505 | cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time; |
| 474 | unsigned int idle_time, wall_time; | 506 | unsigned int idle_time, wall_time, iowait_time; |
| 475 | unsigned int load, load_freq; | 507 | unsigned int load, load_freq; |
| 476 | int freq_avg; | 508 | int freq_avg; |
| 477 | 509 | ||
| 478 | j_dbs_info = &per_cpu(od_cpu_dbs_info, j); | 510 | j_dbs_info = &per_cpu(od_cpu_dbs_info, j); |
| 479 | 511 | ||
| 480 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); | 512 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); |
| 513 | cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time); | ||
| 481 | 514 | ||
| 482 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, | 515 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, |
| 483 | j_dbs_info->prev_cpu_wall); | 516 | j_dbs_info->prev_cpu_wall); |
| @@ -487,6 +520,10 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 487 | j_dbs_info->prev_cpu_idle); | 520 | j_dbs_info->prev_cpu_idle); |
| 488 | j_dbs_info->prev_cpu_idle = cur_idle_time; | 521 | j_dbs_info->prev_cpu_idle = cur_idle_time; |
| 489 | 522 | ||
| 523 | iowait_time = (unsigned int) cputime64_sub(cur_iowait_time, | ||
| 524 | j_dbs_info->prev_cpu_iowait); | ||
| 525 | j_dbs_info->prev_cpu_iowait = cur_iowait_time; | ||
| 526 | |||
| 490 | if (dbs_tuners_ins.ignore_nice) { | 527 | if (dbs_tuners_ins.ignore_nice) { |
| 491 | cputime64_t cur_nice; | 528 | cputime64_t cur_nice; |
| 492 | unsigned long cur_nice_jiffies; | 529 | unsigned long cur_nice_jiffies; |
| @@ -504,6 +541,16 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
| 504 | idle_time += jiffies_to_usecs(cur_nice_jiffies); | 541 | idle_time += jiffies_to_usecs(cur_nice_jiffies); |
| 505 | } | 542 | } |
| 506 | 543 | ||
| 544 | /* | ||
| 545 | * For the purpose of ondemand, waiting for disk IO is an | ||
| 546 | * indication that you're performance critical, and not that | ||
| 547 | * the system is actually idle. So subtract the iowait time | ||
| 548 | * from the cpu idle time. | ||
| 549 | */ | ||
| 550 | |||
| 551 | if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time) | ||
| 552 | idle_time -= iowait_time; | ||
| 553 | |||
| 507 | if (unlikely(!wall_time || wall_time < idle_time)) | 554 | if (unlikely(!wall_time || wall_time < idle_time)) |
| 508 | continue; | 555 | continue; |
| 509 | 556 | ||
| @@ -617,6 +664,29 @@ static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | |||
| 617 | cancel_delayed_work_sync(&dbs_info->work); | 664 | cancel_delayed_work_sync(&dbs_info->work); |
| 618 | } | 665 | } |
| 619 | 666 | ||
| 667 | /* | ||
| 668 | * Not all CPUs want IO time to be accounted as busy; this dependson how | ||
| 669 | * efficient idling at a higher frequency/voltage is. | ||
| 670 | * Pavel Machek says this is not so for various generations of AMD and old | ||
| 671 | * Intel systems. | ||
| 672 | * Mike Chan (androidlcom) calis this is also not true for ARM. | ||
| 673 | * Because of this, whitelist specific known (series) of CPUs by default, and | ||
| 674 | * leave all others up to the user. | ||
| 675 | */ | ||
| 676 | static int should_io_be_busy(void) | ||
| 677 | { | ||
| 678 | #if defined(CONFIG_X86) | ||
| 679 | /* | ||
| 680 | * For Intel, Core 2 (model 15) andl later have an efficient idle. | ||
| 681 | */ | ||
| 682 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | ||
| 683 | boot_cpu_data.x86 == 6 && | ||
| 684 | boot_cpu_data.x86_model >= 15) | ||
| 685 | return 1; | ||
| 686 | #endif | ||
| 687 | return 0; | ||
| 688 | } | ||
| 689 | |||
| 620 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 690 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
| 621 | unsigned int event) | 691 | unsigned int event) |
| 622 | { | 692 | { |
| @@ -679,6 +749,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 679 | dbs_tuners_ins.sampling_rate = | 749 | dbs_tuners_ins.sampling_rate = |
| 680 | max(min_sampling_rate, | 750 | max(min_sampling_rate, |
| 681 | latency * LATENCY_MULTIPLIER); | 751 | latency * LATENCY_MULTIPLIER); |
| 752 | dbs_tuners_ins.io_is_busy = should_io_be_busy(); | ||
| 682 | } | 753 | } |
| 683 | mutex_unlock(&dbs_mutex); | 754 | mutex_unlock(&dbs_mutex); |
| 684 | 755 | ||
