aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-08-06 13:23:10 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-09 21:24:47 -0400
commitfe492f3f0332e23cc6ca4913e5a2ed78e1888902 (patch)
tree0e87539040aabaf02babc0edc49fbb27610b0e3b /drivers/cpufreq
parenteb608521f1e25a8c14295b6d9a3853c3cd8c6cf8 (diff)
cpufreq: Fix broken usage of governor->owner's refcount
The cpufreq governor owner refcount usage is broken. We should only increment that refcount when a CPUFREQ_GOV_POLICY_INIT event has come and it should only be decremented if CPUFREQ_GOV_POLICY_EXIT has come. Currently, there can be situations where the governor is in use, but we have allowed it to be unloaded which may result in undefined behavior. Let's fix it. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 37af929746af..f149e14f77c7 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1709,8 +1709,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
1709 } 1709 }
1710 } 1710 }
1711 1711
1712 if (!try_module_get(policy->governor->owner)) 1712 if (event == CPUFREQ_GOV_POLICY_INIT)
1713 return -EINVAL; 1713 if (!try_module_get(policy->governor->owner))
1714 return -EINVAL;
1714 1715
1715 pr_debug("__cpufreq_governor for CPU %u, event %u\n", 1716 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
1716 policy->cpu, event); 1717 policy->cpu, event);
@@ -1719,6 +1720,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
1719 if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || 1720 if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
1720 (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { 1721 (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
1721 mutex_unlock(&cpufreq_governor_lock); 1722 mutex_unlock(&cpufreq_governor_lock);
1723 if (event == CPUFREQ_GOV_POLICY_INIT)
1724 module_put(policy->governor->owner);
1722 return -EBUSY; 1725 return -EBUSY;
1723 } 1726 }
1724 1727
@@ -1746,11 +1749,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
1746 mutex_unlock(&cpufreq_governor_lock); 1749 mutex_unlock(&cpufreq_governor_lock);
1747 } 1750 }
1748 1751
1749 /* we keep one module reference alive for 1752 if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
1750 each CPU governed by this CPU */ 1753 ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
1751 if ((event != CPUFREQ_GOV_START) || ret)
1752 module_put(policy->governor->owner);
1753 if ((event == CPUFREQ_GOV_STOP) && !ret)
1754 module_put(policy->governor->owner); 1754 module_put(policy->governor->owner);
1755 1755
1756 return ret; 1756 return ret;