aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@openvz.org>2012-12-14 18:22:02 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-03 07:11:18 -0500
commit56836fb4dab8fe906b934b231b04c33c180f8da5 (patch)
tree4ad98361223482eeb8b0f3a4485b7bb4ba4c012d
parentd1c3ed669a2d452cacfb48c2d171a1f364dae2ed (diff)
cpufreq / stats: fix race between stats allocation and first usage
This patch forces complete struct cpufreq_stats allocation for all cpus before registering CPUFREQ_TRANSITION_NOTIFIER notifier, otherwise in some conditions cpufreq_stat_notifier_trans() can be called in the middle of stats allocation, in this case cpufreq_stats_table already exists, but stat->freq_table is NULL. Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/cpufreq_stats.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index e40e50809644..9d7732b81044 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -364,18 +364,21 @@ static int __init cpufreq_stats_init(void)
364 if (ret) 364 if (ret)
365 return ret; 365 return ret;
366 366
367 register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
368 for_each_online_cpu(cpu)
369 cpufreq_update_policy(cpu);
370
367 ret = cpufreq_register_notifier(&notifier_trans_block, 371 ret = cpufreq_register_notifier(&notifier_trans_block,
368 CPUFREQ_TRANSITION_NOTIFIER); 372 CPUFREQ_TRANSITION_NOTIFIER);
369 if (ret) { 373 if (ret) {
370 cpufreq_unregister_notifier(&notifier_policy_block, 374 cpufreq_unregister_notifier(&notifier_policy_block,
371 CPUFREQ_POLICY_NOTIFIER); 375 CPUFREQ_POLICY_NOTIFIER);
376 unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
377 for_each_online_cpu(cpu)
378 cpufreq_stats_free_table(cpu);
372 return ret; 379 return ret;
373 } 380 }
374 381
375 register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
376 for_each_online_cpu(cpu) {
377 cpufreq_update_policy(cpu);
378 }
379 return 0; 382 return 0;
380} 383}
381static void __exit cpufreq_stats_exit(void) 384static void __exit cpufreq_stats_exit(void)