On Sunday, September 01, 2013 10:56:02 AM Viresh Kumar wrote:
We can't take a big lock around __cpufreq_governor() as this causes recursive locking for some cases. But calls to this routine must be serialized for every policy.
Care to explain here why it must be serialized?
Lets introduce another variable which would guarantee serialization here.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org
drivers/cpufreq/cpufreq.c | 7 ++++++- include/linux/cpufreq.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f320a20..4d5723db 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1692,13 +1692,15 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, policy->cpu, event); mutex_lock(&cpufreq_governor_lock);
- if ((policy->governor_enabled && (event == CPUFREQ_GOV_START)) ||
- if (policy->governor_busy ||
(policy->governor_enabled && (event == CPUFREQ_GOV_START)) ||
Again, broken white space, but I can fix it up.
(!policy->governor_enabled && ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_STOP)))) { mutex_unlock(&cpufreq_governor_lock); return -EBUSY;
}
- policy->governor_busy = true; if (event == CPUFREQ_GOV_STOP) policy->governor_enabled = false; else if (event == CPUFREQ_GOV_START)
@@ -1727,6 +1729,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret)) module_put(policy->governor->owner);
- mutex_lock(&cpufreq_governor_lock);
- policy->governor_busy = false;
- mutex_unlock(&cpufreq_governor_lock); return ret;
} diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index d568f39..cca885d 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -76,6 +76,7 @@ struct cpufreq_policy { struct cpufreq_governor *governor; /* see below */ void *governor_data; bool governor_enabled; /* governor start/stop flag */
- bool governor_busy;
struct work_struct update; /* if update_policy() needs to be * called, but you're in IRQ context */