diff options
| author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2012-12-14 18:22:02 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-03 07:11:18 -0500 |
| commit | 56836fb4dab8fe906b934b231b04c33c180f8da5 (patch) | |
| tree | 4ad98361223482eeb8b0f3a4485b7bb4ba4c012d | |
| parent | d1c3ed669a2d452cacfb48c2d171a1f364dae2ed (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.c | 11 |
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(¬ifier_trans_block, | 371 | ret = cpufreq_register_notifier(¬ifier_trans_block, |
| 368 | CPUFREQ_TRANSITION_NOTIFIER); | 372 | CPUFREQ_TRANSITION_NOTIFIER); |
| 369 | if (ret) { | 373 | if (ret) { |
| 370 | cpufreq_unregister_notifier(¬ifier_policy_block, | 374 | cpufreq_unregister_notifier(¬ifier_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 | } |
| 381 | static void __exit cpufreq_stats_exit(void) | 384 | static void __exit cpufreq_stats_exit(void) |
