forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
eb608521f1
commit
fe492f3f03
@ -1709,8 +1709,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
|
||||
}
|
||||
}
|
||||
|
||||
if (!try_module_get(policy->governor->owner))
|
||||
return -EINVAL;
|
||||
if (event == CPUFREQ_GOV_POLICY_INIT)
|
||||
if (!try_module_get(policy->governor->owner))
|
||||
return -EINVAL;
|
||||
|
||||
pr_debug("__cpufreq_governor for CPU %u, event %u\n",
|
||||
policy->cpu, event);
|
||||
@ -1719,6 +1720,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
|
||||
if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
|
||||
(policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
|
||||
mutex_unlock(&cpufreq_governor_lock);
|
||||
if (event == CPUFREQ_GOV_POLICY_INIT)
|
||||
module_put(policy->governor->owner);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@ -1746,11 +1749,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
|
||||
mutex_unlock(&cpufreq_governor_lock);
|
||||
}
|
||||
|
||||
/* we keep one module reference alive for
|
||||
each CPU governed by this CPU */
|
||||
if ((event != CPUFREQ_GOV_START) || ret)
|
||||
module_put(policy->governor->owner);
|
||||
if ((event == CPUFREQ_GOV_STOP) && !ret)
|
||||
if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
|
||||
((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
|
||||
module_put(policy->governor->owner);
|
||||
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user