Skip to content

Commit

Permalink
cpufreq: governors: Fix CPUFREQ_GOV_POLICY_{INIT|EXIT} notifiers
Browse files Browse the repository at this point in the history
There are two types of INIT/EXIT activities that we need to do for
governors:
 - Done only once per governor (doesn't depend how many instances of
   the governor there are). eg: cpufreq_register_notifier() for
   conservative governor.
 - Done per governor instance, eg: sysfs_{create|remove}_group().

There were some corner cases where current code isn't able to handle
them separately and so failing for some test cases.

We use two separate variables now for keeping track of above two
requirements.
 - governor->initialized for first one
 - dbs_data->usage_count for per governor instance

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Viresh Kumar authored and Rafael J. Wysocki committed May 12, 2013
1 parent 2b80f31 commit a97c98a
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
11 changes: 7 additions & 4 deletions drivers/cpufreq/cpufreq_governor.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (have_governor_per_policy()) {
WARN_ON(dbs_data);
} else if (dbs_data) {
dbs_data->usage_count++;
policy->governor_data = dbs_data;
return 0;
}
Expand All @@ -266,6 +267,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
}

dbs_data->cdata = cdata;
dbs_data->usage_count = 1;
rc = cdata->init(dbs_data);
if (rc) {
pr_err("%s: POLICY_INIT: init() failed\n", __func__);
Expand Down Expand Up @@ -294,7 +296,8 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
latency * LATENCY_MULTIPLIER));

if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
if ((cdata->governor == GOV_CONSERVATIVE) &&
(!policy->governor->initialized)) {
struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;

cpufreq_register_notifier(cs_ops->notifier_block,
Expand All @@ -306,12 +309,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,

return 0;
case CPUFREQ_GOV_POLICY_EXIT:
if ((policy->governor->initialized == 1) ||
have_governor_per_policy()) {
if (!--dbs_data->usage_count) {
sysfs_remove_group(get_governor_parent_kobj(policy),
get_sysfs_attr(dbs_data));

if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
(policy->governor->initialized == 1)) {
struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;

cpufreq_unregister_notifier(cs_ops->notifier_block,
Expand Down
1 change: 1 addition & 0 deletions drivers/cpufreq/cpufreq_governor.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ struct common_dbs_data {
struct dbs_data {
struct common_dbs_data *cdata;
unsigned int min_sampling_rate;
int usage_count;
void *tuners;

/* dbs_mutex protects dbs_enable in governor start/stop */
Expand Down

0 comments on commit a97c98a

Please sign in to comment.