summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Wagner <mwagner@nvidia.com>2012-09-17 16:06:15 -0700
committerMrutyunjay Sawant <msawant@nvidia.com>2012-09-20 06:27:24 -0700
commitae934e1ea7243000e399486823508b4a180254b5 (patch)
tree177d36531cbd5642fd0aa025629ddbd29211ed02
parent4c12e7369dcd7789ff2477279e28a792dca2eac7 (diff)
cpufreq: interactive: Unify Governor Lock Strategy
Change our locking strategy to be the same as the conservative and ondemand governor for GOV_START and GOV_STOP to allow for correct handling of multiple CPUs Bug 1049258 Change-Id: I15ab620e2f9d47b00ec8186c224eb719b9735aa7 Signed-off-by: Matt Wagner <mwagner@nvidia.com> Reviewed-on: http://git-master/r/133360 Reviewed-by: Satya Popuri <spopuri@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 7821e41ab332..cf6ba6c1958e 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -30,8 +30,6 @@
#include <asm/cputime.h>
-static atomic_t active_count = ATOMIC_INIT(0);
-
struct cpufreq_interactive_cpuinfo {
struct timer_list cpu_timer;
int timer_idlecancel;
@@ -61,7 +59,9 @@ static spinlock_t up_cpumask_lock;
static cpumask_t down_cpumask;
static spinlock_t down_cpumask_lock;
static struct mutex set_speed_lock;
+static struct mutex gov_state_lock;
static struct kobject *interactive_kobj;
+static unsigned int active_count;
/* Go to max speed when CPU load at or above this value. */
#define DEFAULT_GO_MAXSPEED_LOAD 85
@@ -652,21 +652,25 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
mod_timer(&pcpu->cpu_timer, jiffies + 2);
}
+ mutex_lock(&gov_state_lock);
+ active_count++;
/*
* Do not register the idle hook and create sysfs
* entries if we have already done so.
*/
- if (atomic_inc_return(&active_count) > 1)
- return 0;
-
- rc = sysfs_create_group(cpufreq_global_kobject,
- &interactive_attr_group);
- interactive_kobj = kobject_create_and_add(
- "gov_interactive",
- cpufreq_global_kobject);
- kobject_uevent(interactive_kobj, KOBJ_ADD);
- if (rc)
- return rc;
+ if (active_count == 1) {
+ rc = sysfs_create_group(cpufreq_global_kobject,
+ &interactive_attr_group);
+ interactive_kobj = kobject_create_and_add(
+ "gov_interactive",
+ cpufreq_global_kobject);
+ kobject_uevent(interactive_kobj, KOBJ_ADD);
+ if (rc) {
+ mutex_unlock(&gov_state_lock);
+ return rc;
+ }
+ }
+ mutex_unlock(&gov_state_lock);
break;
@@ -687,13 +691,18 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
}
flush_work(&freq_scale_down_work);
- if (atomic_dec_return(&active_count) > 0)
- return 0;
+ mutex_lock(&gov_state_lock);
+
+ active_count--;
+
+ if (active_count == 0) {
+ sysfs_remove_group(cpufreq_global_kobject,
+ &interactive_attr_group);
+ kobject_uevent(interactive_kobj, KOBJ_REMOVE);
+ kobject_put(interactive_kobj);
+ }
- sysfs_remove_group(cpufreq_global_kobject,
- &interactive_attr_group);
- kobject_uevent(interactive_kobj, KOBJ_REMOVE);
- kobject_put(interactive_kobj);
+ mutex_unlock(&gov_state_lock);
break;
@@ -771,6 +780,7 @@ static int __init cpufreq_interactive_init(void)
spin_lock_init(&up_cpumask_lock);
spin_lock_init(&down_cpumask_lock);
mutex_init(&set_speed_lock);
+ mutex_init(&gov_state_lock);
idle_notifier_register(&cpufreq_interactive_idle_nb);