diff options
author | Thomas Renninger <trenn@suse.de> | 2007-07-09 14:35:28 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2007-07-13 01:29:51 -0400 |
commit | 084f34939424161669467c19280dbcf637730314 (patch) | |
tree | 85285adb98b7306a28152cf48bfae98d3f1f05c8 /drivers/cpufreq/cpufreq.c | |
parent | 91973de736bc97dc04156242c5a4b00993b6c902 (diff) |
[CPUFREQ] Restore previously used governor on a hot-replugged CPU
Negative side effect: needs NR_CPUs pointer array of memory in
CONFIG_HOTPLUG_CPU case.
Still needs userspace track keeping and rewriting of governors if governors
change while a CPU is not active (always the governor at CPU remove time is
restored).
Move of policy->user_policy.governor assignment is just a minor cleanup.
http://bugzilla.kernel.org/show_bug.cgi?id=8671
Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 99f9c3c23845..2f6a73c01b71 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -39,6 +39,10 @@ | |||
39 | */ | 39 | */ |
40 | static struct cpufreq_driver *cpufreq_driver; | 40 | static struct cpufreq_driver *cpufreq_driver; |
41 | static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; | 41 | static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; |
42 | #ifdef CONFIG_HOTPLUG_CPU | ||
43 | /* This one keeps track of the previously set governor of a removed CPU */ | ||
44 | static struct cpufreq_governor *cpufreq_cpu_governor[NR_CPUS]; | ||
45 | #endif | ||
42 | static DEFINE_SPINLOCK(cpufreq_driver_lock); | 46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); |
43 | 47 | ||
44 | /* | 48 | /* |
@@ -770,9 +774,17 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
770 | } | 774 | } |
771 | policy->user_policy.min = policy->cpuinfo.min_freq; | 775 | policy->user_policy.min = policy->cpuinfo.min_freq; |
772 | policy->user_policy.max = policy->cpuinfo.max_freq; | 776 | policy->user_policy.max = policy->cpuinfo.max_freq; |
773 | policy->user_policy.governor = policy->governor; | ||
774 | 777 | ||
775 | #ifdef CONFIG_SMP | 778 | #ifdef CONFIG_SMP |
779 | |||
780 | #ifdef CONFIG_HOTPLUG_CPU | ||
781 | if (cpufreq_cpu_governor[cpu]){ | ||
782 | policy->governor = cpufreq_cpu_governor[cpu]; | ||
783 | dprintk("Restoring governor %s for cpu %d\n", | ||
784 | policy->governor->name, cpu); | ||
785 | } | ||
786 | #endif | ||
787 | |||
776 | for_each_cpu_mask(j, policy->cpus) { | 788 | for_each_cpu_mask(j, policy->cpus) { |
777 | if (cpu == j) | 789 | if (cpu == j) |
778 | continue; | 790 | continue; |
@@ -873,6 +885,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
873 | /* set default policy */ | 885 | /* set default policy */ |
874 | ret = __cpufreq_set_policy(policy, &new_policy); | 886 | ret = __cpufreq_set_policy(policy, &new_policy); |
875 | policy->user_policy.policy = policy->policy; | 887 | policy->user_policy.policy = policy->policy; |
888 | policy->user_policy.governor = policy->governor; | ||
876 | 889 | ||
877 | unlock_policy_rwsem_write(cpu); | 890 | unlock_policy_rwsem_write(cpu); |
878 | 891 | ||
@@ -969,6 +982,11 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) | |||
969 | } | 982 | } |
970 | 983 | ||
971 | #ifdef CONFIG_SMP | 984 | #ifdef CONFIG_SMP |
985 | |||
986 | #ifdef CONFIG_HOTPLUG_CPU | ||
987 | cpufreq_cpu_governor[cpu] = data->governor; | ||
988 | #endif | ||
989 | |||
972 | /* if we have other CPUs still registered, we need to unlink them, | 990 | /* if we have other CPUs still registered, we need to unlink them, |
973 | * or else wait_for_completion below will lock up. Clean the | 991 | * or else wait_for_completion below will lock up. Clean the |
974 | * cpufreq_cpu_data[] while holding the lock, and remove the sysfs | 992 | * cpufreq_cpu_data[] while holding the lock, and remove the sysfs |
@@ -989,6 +1007,9 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) | |||
989 | if (j == cpu) | 1007 | if (j == cpu) |
990 | continue; | 1008 | continue; |
991 | dprintk("removing link for cpu %u\n", j); | 1009 | dprintk("removing link for cpu %u\n", j); |
1010 | #ifdef CONFIG_HOTPLUG_CPU | ||
1011 | cpufreq_cpu_governor[j] = data->governor; | ||
1012 | #endif | ||
992 | cpu_sys_dev = get_cpu_sysdev(j); | 1013 | cpu_sys_dev = get_cpu_sysdev(j); |
993 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); | 1014 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); |
994 | cpufreq_cpu_put(data); | 1015 | cpufreq_cpu_put(data); |