From 0a4b2ccc555fa2ca6873d60219047104e4805d45 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 21 May 2007 07:20:04 -0500 Subject: [CPUFREQ] check return value of sysfs_create_file Eliminate build warning (sysfs_create_file return value must be checked) Signed-off-by: Thomas Renninger Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index eb37fba9b7ef..0521427a571e 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -826,13 +826,18 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) /* set up files for this cpu device */ drv_attr = cpufreq_driver->attr; while ((drv_attr) && (*drv_attr)) { - sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); + if (sysfs_create_file(&policy->kobj, &((*drv_attr)->attr))) + goto err_out_driver_exit; drv_attr++; } - if (cpufreq_driver->get) - sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); - if (cpufreq_driver->target) - sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); + if (cpufreq_driver->get){ + if (sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr)) + goto err_out_driver_exit; + } + if (cpufreq_driver->target){ + if (sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr)) + goto err_out_driver_exit; + } spin_lock_irqsave(&cpufreq_driver_lock, flags); for_each_cpu_mask(j, policy->cpus) { -- cgit v1.2.3 From c7f652e0487a35c16f6cd72707232b6a28647a10 Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Wed, 20 Jun 2007 14:24:00 -0700 Subject: [CPUFREQ] Keep userspace governor quiet when it is not being used Userspace governor registers a frequency change notifier at init time, even when no CPU is set to userspace governor. Make it register only when atleast one CPU is using userspace. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_userspace.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 860345c7799a..b1348ff9fcf4 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -37,6 +37,7 @@ static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */ static unsigned int cpu_is_managed[NR_CPUS]; static DEFINE_MUTEX (userspace_mutex); +static int cpus_using_userspace_governor; #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg) @@ -47,7 +48,11 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, { struct cpufreq_freqs *freq = data; - dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n", freq->cpu, freq->new); + if (!cpu_is_managed[freq->cpu]) + return 0; + + dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n", + freq->cpu, freq->new); cpu_cur_freq[freq->cpu] = freq->new; return 0; @@ -142,6 +147,13 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, if (rc) goto start_out; + if (cpus_using_userspace_governor == 0) { + cpufreq_register_notifier( + &userspace_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + } + cpus_using_userspace_governor++; + cpu_is_managed[cpu] = 1; cpu_min_freq[cpu] = policy->min; cpu_max_freq[cpu] = policy->max; @@ -153,6 +165,13 @@ start_out: break; case CPUFREQ_GOV_STOP: mutex_lock(&userspace_mutex); + cpus_using_userspace_governor--; + if (cpus_using_userspace_governor == 0) { + cpufreq_unregister_notifier( + &userspace_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + } + cpu_is_managed[cpu] = 0; cpu_min_freq[cpu] = 0; cpu_max_freq[cpu] = 0; @@ -198,7 +217,6 @@ EXPORT_SYMBOL(cpufreq_gov_userspace); static int __init cpufreq_gov_userspace_init(void) { - cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); return cpufreq_register_governor(&cpufreq_gov_userspace); } @@ -206,7 +224,6 @@ static int __init cpufreq_gov_userspace_init(void) static void __exit cpufreq_gov_userspace_exit(void) { cpufreq_unregister_governor(&cpufreq_gov_userspace); - cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); } -- cgit v1.2.3 From 0af99b13c9f323e658b4f1d69a1ccae7d6f3f80a Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Wed, 20 Jun 2007 14:24:52 -0700 Subject: [CPUFREQ] ondemand: add a check to avoid negative load calculation Due to rounding and inexact jiffy accounting, idle_ticks can sometimes be higher than total_ticks. Make sure those cases are handled as zero load case. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 8532bb79e5fc..dc6f357390e2 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -325,7 +325,7 @@ static struct attribute_group dbs_attr_group = { static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) { unsigned int idle_ticks, total_ticks; - unsigned int load; + unsigned int load = 0; cputime64_t cur_jiffies; struct cpufreq_policy *policy; @@ -370,7 +370,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) if (tmp_idle_ticks < idle_ticks) idle_ticks = tmp_idle_ticks; } - load = (100 * (total_ticks - idle_ticks)) / total_ticks; + if (likely(total_ticks > idle_ticks)) + load = (100 * (total_ticks - idle_ticks)) / total_ticks; /* Check for frequency increase */ if (load > dbs_tuners_ins.up_threshold) { -- cgit v1.2.3 From ea48761519bd40d7a881c587b5f3177664b2987e Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Wed, 20 Jun 2007 14:26:24 -0700 Subject: [CPUFREQ] ondemand: fix tickless accounting and software coordination bug With tickless kernel and software coordination os P-states, ondemand can look at wrong idle statistics. This can happen when ondemand sampling is happening on CPU 0 and due to software coordination sampling also looks at utilization of CPU 1. If CPU 1 is in tickless state at that moment, its idle statistics will not be uptodate and CPU 0 thinks CPU 1 is idle for less amount of time than it actually is. This can be resolved by looking at all the busy times of CPUs, which is accurate, even with tickless, and use that to determine idle time in a round about way (total time - busy time). Thanks to Arjan for originally reporting the ondemand bug on Lenovo T61. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index dc6f357390e2..e794527e4925 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -96,15 +96,25 @@ static struct dbs_tuners { static inline cputime64_t get_cpu_idle_time(unsigned int cpu) { - cputime64_t retval; + cputime64_t idle_time; + cputime64_t cur_jiffies; + cputime64_t busy_time; - retval = cputime64_add(kstat_cpu(cpu).cpustat.idle, - kstat_cpu(cpu).cpustat.iowait); + cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); + busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user, + kstat_cpu(cpu).cpustat.system); - if (dbs_tuners_ins.ignore_nice) - retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal); - return retval; + if (!dbs_tuners_ins.ignore_nice) { + busy_time = cputime64_add(busy_time, + kstat_cpu(cpu).cpustat.nice); + } + + idle_time = cputime64_sub(cur_jiffies, busy_time); + return idle_time; } /* @@ -339,7 +349,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); total_ticks = (unsigned int) cputime64_sub(cur_jiffies, this_dbs_info->prev_cpu_wall); - this_dbs_info->prev_cpu_wall = cur_jiffies; + this_dbs_info->prev_cpu_wall = get_jiffies_64(); + if (!total_ticks) return; /* -- cgit v1.2.3 From 58a7295bc8073b9e668c329cb9ceb5b668c2b15d Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 14 Jun 2007 00:28:15 +0200 Subject: [CPUFREQ] Fix sysfs_create_file return value handling Commit 0a4b2ccc555fa2ca6873d60219047104e4805d45 in cpufreq.git eliminates the build warnings but does not pass on the error code of sysfs_create_file to the function calling cpufreq_add_dev. Instead some previous value of ret would be returned. Signed-off-by: Tobias Klauser Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0521427a571e..0db9e1bda322 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -826,16 +826,19 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) /* set up files for this cpu device */ drv_attr = cpufreq_driver->attr; while ((drv_attr) && (*drv_attr)) { - if (sysfs_create_file(&policy->kobj, &((*drv_attr)->attr))) + ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); + if (ret) goto err_out_driver_exit; drv_attr++; } if (cpufreq_driver->get){ - if (sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr)) + ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); + if (ret) goto err_out_driver_exit; } if (cpufreq_driver->target){ - if (sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr)) + ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); + if (ret) goto err_out_driver_exit; } -- cgit v1.2.3