Skip to content

Commit

Permalink
[CPUFREQ] Fix stale cpufreq_cpu_governor pointer
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Prarit Bhargava authored and Dave Jones committed Nov 18, 2009
1 parent 54c9a35 commit 90e41ba
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,10 +951,13 @@ int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
static int cpufreq_add_dev(struct sys_device *sys_dev)
{
unsigned int cpu = sys_dev->id;
int ret = 0;
int ret = 0, found = 0;
struct cpufreq_policy *policy;
unsigned long flags;
unsigned int j;
#ifdef CONFIG_HOTPLUG_CPU
int sibling;
#endif

if (cpu_is_offline(cpu))
return 0;
Expand Down Expand Up @@ -1001,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
INIT_WORK(&policy->update, handle_update);

/* Set governor before ->init, so that driver could check it */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
#ifdef CONFIG_HOTPLUG_CPU
for_each_online_cpu(sibling) {
struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
if (cp && cp->governor &&
(cpumask_test_cpu(cpu, cp->related_cpus))) {
policy->governor = cp->governor;
found = 1;
break;
}
}
#endif
if (!found)
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
Expand Down Expand Up @@ -1610,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);

void cpufreq_unregister_governor(struct cpufreq_governor *governor)
{
#ifdef CONFIG_HOTPLUG_CPU
int cpu;
#endif

if (!governor)
return;

#ifdef CONFIG_HOTPLUG_CPU
for_each_present_cpu(cpu) {
if (cpu_online(cpu))
continue;
if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
}
#endif

mutex_lock(&cpufreq_governor_mutex);
list_del(&governor->governor_list);
mutex_unlock(&cpufreq_governor_mutex);
Expand Down

0 comments on commit 90e41ba

Please sign in to comment.