From c797732241994154461b1eb82415f43825edfa1d Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Wed, 2 Apr 2014 12:14:25 +0200 Subject: [PATCH] cpufreq:governor: Add serialization to the cpufreq_governor_dbs() function It is necessary to serialize access to cpufreq_governor_dbs() function, since it can be accessed from different, not protected by any mutex paths like sysfs boost attribute or LAB governor internals. Change-Id: Id7b62db6ca0b7c28f5e8c6286aec312d3d0c971e Signed-off-by: Lukasz Majewski --- drivers/cpufreq/cpufreq_governor.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 9b7352c..e62e94f 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -28,6 +28,7 @@ #include #include "cpufreq_governor.h" +static DEFINE_MUTEX(cpufreq_governor_lock); static struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy) { @@ -250,6 +251,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, int rc; int governor = cdata->governor; + mutex_lock(&cpufreq_governor_lock); if (have_governor_per_policy()) dbs_data = policy->governor_data; else @@ -264,12 +266,14 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, } else if (dbs_data) { dbs_data->usage_count++; policy->governor_data = dbs_data; + mutex_unlock(&cpufreq_governor_lock); return 0; } dbs_data = kzalloc(sizeof(*dbs_data), GFP_KERNEL); if (!dbs_data) { pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__); + mutex_unlock(&cpufreq_governor_lock); return -ENOMEM; } @@ -279,6 +283,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (rc) { pr_err("%s: POLICY_INIT: init() failed\n", __func__); kfree(dbs_data); + mutex_unlock(&cpufreq_governor_lock); return rc; } @@ -290,6 +295,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (rc) { cdata->exit(dbs_data); kfree(dbs_data); + mutex_unlock(&cpufreq_governor_lock); return rc; } @@ -317,6 +323,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (!have_governor_per_policy()) cdata->gdbs_data = dbs_data; + mutex_unlock(&cpufreq_governor_lock); return 0; case CPUFREQ_GOV_POLICY_EXIT: if (!--dbs_data->usage_count) { @@ -340,6 +347,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, } policy->governor_data = NULL; + mutex_unlock(&cpufreq_governor_lock); return 0; } @@ -347,9 +355,10 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, switch (event) { case CPUFREQ_GOV_START: - if (!policy->cur) + if (!policy->cur) { + mutex_unlock(&cpufreq_governor_lock); return -EINVAL; - + } if (governor == GOV_CONSERVATIVE) { cs_tuners = dbs_data->tuners; cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu); @@ -423,6 +432,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, mutex_unlock(&cpu_cdbs->timer_mutex); break; } + mutex_unlock(&cpufreq_governor_lock); return 0; } EXPORT_SYMBOL_GPL(cpufreq_governor_dbs); -- 2.7.4