aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2009-11-12 09:18:46 -0500
committerDave Jones <davej@redhat.com>2009-11-17 23:15:04 -0500
commit90e41bac100e34f955f48e7686c2fc685ac9aa30 (patch)
tree50ae248a292e85d3e784d12e2e6a37823048d98b
parent54c9a35d9faef06e00e2a941eb8fe674f1886901 (diff)
[CPUFREQ] Fix stale cpufreq_cpu_governor pointer
Dave, Attached is an update of my patch against the cpufreq fixes branch. Before applying the patch I compiled and booted the tree to see if the panic was still there -- to my surprise it was not. This is because of the conversion of cpufreq_cpu_governor to a char[]. While the panic is kaput, the problem of stale data continues and my patch is still valid. It is possible to end up with the wrong governor after hotplug events because CPUFREQ_DEFAULT_GOVERNOR is statically linked to a default, while the cpu siblings may have had a different governor assigned by a user. ie) the patch is still needed in order to keep the governors assigned properly when hotplugging devices Signed-off-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Dave Jones <davej@redhat.com>
-rw-r--r--drivers/cpufreq/cpufreq.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index dab1410d1c0d..ff57c40e9b8b 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -951,10 +951,13 @@ err_out_kobj_put:
951static int cpufreq_add_dev(struct sys_device *sys_dev) 951static int cpufreq_add_dev(struct sys_device *sys_dev)
952{ 952{
953 unsigned int cpu = sys_dev->id; 953 unsigned int cpu = sys_dev->id;
954 int ret = 0; 954 int ret = 0, found = 0;
955 struct cpufreq_policy *policy; 955 struct cpufreq_policy *policy;
956 unsigned long flags; 956 unsigned long flags;
957 unsigned int j; 957 unsigned int j;
958#ifdef CONFIG_HOTPLUG_CPU
959 int sibling;
960#endif
958 961
959 if (cpu_is_offline(cpu)) 962 if (cpu_is_offline(cpu))
960 return 0; 963 return 0;
@@ -1001,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
1001 INIT_WORK(&policy->update, handle_update); 1004 INIT_WORK(&policy->update, handle_update);
1002 1005
1003 /* Set governor before ->init, so that driver could check it */ 1006 /* Set governor before ->init, so that driver could check it */
1004 policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 1007#ifdef CONFIG_HOTPLUG_CPU
1008 for_each_online_cpu(sibling) {
1009 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
1010 if (cp && cp->governor &&
1011 (cpumask_test_cpu(cpu, cp->related_cpus))) {
1012 policy->governor = cp->governor;
1013 found = 1;
1014 break;
1015 }
1016 }
1017#endif
1018 if (!found)
1019 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
1005 /* call driver. From then on the cpufreq must be able 1020 /* call driver. From then on the cpufreq must be able
1006 * to accept all calls to ->verify and ->setpolicy for this CPU 1021 * to accept all calls to ->verify and ->setpolicy for this CPU
1007 */ 1022 */
@@ -1610,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1610 1625
1611void cpufreq_unregister_governor(struct cpufreq_governor *governor) 1626void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1612{ 1627{
1628#ifdef CONFIG_HOTPLUG_CPU
1629 int cpu;
1630#endif
1631
1613 if (!governor) 1632 if (!governor)
1614 return; 1633 return;
1615 1634
1635#ifdef CONFIG_HOTPLUG_CPU
1636 for_each_present_cpu(cpu) {
1637 if (cpu_online(cpu))
1638 continue;
1639 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1640 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1641 }
1642#endif
1643
1616 mutex_lock(&cpufreq_governor_mutex); 1644 mutex_lock(&cpufreq_governor_mutex);
1617 list_del(&governor->governor_list); 1645 list_del(&governor->governor_list);
1618 mutex_unlock(&cpufreq_governor_mutex); 1646 mutex_unlock(&cpufreq_governor_mutex);