cpufreq: interactive: Fix freeing of cached tunabled during module_exit()

To avoid multiple frees of an allocated tunables struct during
module_exit(), the pointer to the allocated tunables should be stored in
only one of the per-CPU cached_tunables pointer.

So, in the case of per policy governor configuration, store the cached
values in the pointer of first CPU in a policy. In the case of one governor
across all policies, store it in the CPU0 pointer.

Change-Id: Id4334246491519ac91ab725a8758b2748f743bb0
Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
This commit is contained in:
Saravana Kannan 2014-07-22 15:42:51 -07:00 committed by David Keitel
parent 249a58c4a5
commit 9993217296

View file

@ -1155,19 +1155,27 @@ static void save_tunables(struct cpufreq_policy *policy,
{
int cpu;
if (have_governor_per_policy()) {
for_each_cpu(cpu, policy->related_cpus) {
WARN_ON(per_cpu(cached_tunables, cpu) &&
per_cpu(cached_tunables, cpu) != tunables);
per_cpu(cached_tunables, cpu) = tunables;
}
} else {
for_each_possible_cpu(cpu) {
WARN_ON(per_cpu(cached_tunables, cpu) &&
per_cpu(cached_tunables, cpu) != tunables);
per_cpu(cached_tunables, cpu) = tunables;
}
}
if (have_governor_per_policy())
cpu = cpumask_first(policy->related_cpus);
else
cpu = 0;
WARN_ON(per_cpu(cached_tunables, cpu) &&
per_cpu(cached_tunables, cpu) != tunables);
per_cpu(cached_tunables, cpu) = tunables;
}
static struct cpufreq_interactive_tunables *restore_tunables(
struct cpufreq_policy *policy)
{
int cpu;
if (have_governor_per_policy())
cpu = cpumask_first(policy->related_cpus);
else
cpu = 0;
return per_cpu(cached_tunables, cpu);
}
static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
@ -1197,7 +1205,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
return 0;
}
tunables = per_cpu(cached_tunables, policy->cpu);
tunables = restore_tunables(policy);
if (!tunables) {
tunables = alloc_tunable(policy);
if (IS_ERR(tunables))