summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-08-06 22:53:13 +0530
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-10 03:24:48 +0200
commit3de9bdeb28638e164d1f0eb38dd68e3f5d2ac95c (patch)
treeefe5c314af79f28840a2a31eb2e2ca992c0258ae
parentadc97d6a735dbb1e94cb4f1bf0b55f258b349941 (diff)
cpufreq: improve error checking on return values of __cpufreq_governor()
The __cpufreq_governor() function can fail in rare cases especially if there are bugs in cpufreq drivers. Thus we must stop processing as soon as this routine fails, otherwise it may result in undefined behavior. This patch adds error checking code whenever this routine is called from any place. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/cpufreq.c48
1 files changed, 36 insertions, 12 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index c9bbfeef92e..37a68746732 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -874,8 +874,13 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
int ret = 0, has_target = !!cpufreq_driver->target;
unsigned long flags;
- if (has_target)
- __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+ if (has_target) {
+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+ if (ret) {
+ pr_err("%s: Failed to stop governor\n", __func__);
+ return ret;
+ }
+ }
lock_policy_rwsem_write(policy->cpu);
@@ -889,8 +894,11 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
unlock_policy_rwsem_write(policy->cpu);
if (has_target) {
- __cpufreq_governor(policy, CPUFREQ_GOV_START);
- __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
+ if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
+ (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
+ pr_err("%s: Failed to start governor\n", __func__);
+ return ret;
+ }
}
/* Don't touch sysfs links during light-weight init */
@@ -1172,7 +1180,7 @@ static int __cpufreq_remove_dev(struct device *dev,
struct subsys_interface *sif, bool frozen)
{
unsigned int cpu = dev->id, cpus;
- int new_cpu;
+ int new_cpu, ret;
unsigned long flags;
struct cpufreq_policy *policy;
struct kobject *kobj;
@@ -1196,8 +1204,13 @@ static int __cpufreq_remove_dev(struct device *dev,
return -EINVAL;
}
- if (cpufreq_driver->target)
- __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+ if (cpufreq_driver->target) {
+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+ if (ret) {
+ pr_err("%s: Failed to stop governor\n", __func__);
+ return ret;
+ }
+ }
#ifdef CONFIG_HOTPLUG_CPU
if (!cpufreq_driver->setpolicy)
@@ -1231,8 +1244,15 @@ static int __cpufreq_remove_dev(struct device *dev,
/* If cpu is last user of policy, free policy */
if (cpus == 1) {
- if (cpufreq_driver->target)
- __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
+ if (cpufreq_driver->target) {
+ ret = __cpufreq_governor(policy,
+ CPUFREQ_GOV_POLICY_EXIT);
+ if (ret) {
+ pr_err("%s: Failed to exit governor\n",
+ __func__);
+ return ret;
+ }
+ }
if (!frozen) {
lock_policy_rwsem_read(cpu);
@@ -1263,8 +1283,12 @@ static int __cpufreq_remove_dev(struct device *dev,
cpufreq_policy_free(policy);
} else {
if (cpufreq_driver->target) {
- __cpufreq_governor(policy, CPUFREQ_GOV_START);
- __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
+ if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
+ (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
+ pr_err("%s: Failed to start governor\n",
+ __func__);
+ return ret;
+ }
}
}
@@ -1912,7 +1936,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *policy,
/* might be a policy change, too, so fall through */
}
pr_debug("governor: change or update limits\n");
- __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
+ ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
}
error_out: