diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2013-02-01 05:42:58 +0000 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-02-02 01:29:31 +0100 |
commit | b394058f064848deac7a7cd6942b6521d7b3fe1d (patch) | |
tree | 2e6272ca452cf2d116f00a561344a4672f751063 | |
parent | 4447266b842d27f77b017a59eb9dc38ad7b299f1 (diff) |
cpufreq: governors: Reset tunables only for cpufreq_unregister_governor()
Currently, whenever governor->governor() is called for CPUFRREQ_GOV_START event
we reset few tunables of governor. Which isn't correct, as this routine is
called for every cpu hot-[un]plugging event. We should actually be resetting
these only when the governor module is removed and re-installed.
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.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 24 | ||||
-rw-r--r-- | include/linux/cpufreq.h | 1 |
3 files changed, 21 insertions, 8 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1cea7a1eac13..0b4be4481433 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1562,6 +1562,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, policy->cpu, event); ret = policy->governor->governor(policy, event); + if (!policy->governor->initialized && (event == CPUFREQ_GOV_START)) + policy->governor->initialized = 1; + /* we keep one module reference alive for each CPU governed by this CPU */ if ((event != CPUFREQ_GOV_START) || ret) @@ -1585,6 +1588,7 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) mutex_lock(&cpufreq_governor_mutex); + governor->initialized = 0; err = -EBUSY; if (__find_governor(governor->name) == NULL) { err = 0; diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 7aaa9b151940..79795c4bf611 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -254,11 +254,6 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, return rc; } - /* policy latency is in nS. Convert it to uS first */ - latency = policy->cpuinfo.transition_latency / 1000; - if (latency == 0) - latency = 1; - /* * conservative does not implement micro like ondemand * governor, thus we are bound to jiffes/HZ @@ -270,20 +265,33 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, cpufreq_register_notifier(cs_ops->notifier_block, CPUFREQ_TRANSITION_NOTIFIER); - dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * - jiffies_to_usecs(10); + if (!policy->governor->initialized) + dbs_data->min_sampling_rate = + MIN_SAMPLING_RATE_RATIO * + jiffies_to_usecs(10); } else { od_dbs_info->rate_mult = 1; od_dbs_info->sample_type = OD_NORMAL_SAMPLE; od_ops->powersave_bias_init_cpu(cpu); - od_tuners->io_is_busy = od_ops->io_busy(); + + if (!policy->governor->initialized) + od_tuners->io_is_busy = od_ops->io_busy(); } + if (policy->governor->initialized) + goto unlock; + + /* policy latency is in nS. Convert it to uS first */ + latency = policy->cpuinfo.transition_latency / 1000; + if (latency == 0) + latency = 1; + /* Bring kernel and HW constraints together */ dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate, MIN_LATENCY_MULTIPLIER * latency); *sampling_rate = max(dbs_data->min_sampling_rate, latency * LATENCY_MULTIPLIER); +unlock: mutex_unlock(&dbs_data->mutex); /* Initiate timer time stamp */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index feb360c8aa88..6bf3f2d12c90 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -183,6 +183,7 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; + int initialized; int (*governor) (struct cpufreq_policy *policy, unsigned int event); ssize_t (*show_setspeed) (struct cpufreq_policy *policy, |