From ae934e1ea7243000e399486823508b4a180254b5 Mon Sep 17 00:00:00 2001 From: Matt Wagner Date: Mon, 17 Sep 2012 16:06:15 -0700 Subject: 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 Reviewed-on: http://git-master/r/133360 Reviewed-by: Satya Popuri Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Dan Willemsen --- drivers/cpufreq/cpufreq_interactive.c | 48 +++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers/cpufreq') 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 -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); -- cgit v1.2.3