diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-07-29 19:45:07 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-07-31 16:01:19 -0400 |
commit | fdd320da84c63092fe6e155cb7b8d80f7f765fa9 (patch) | |
tree | 43945999294bf7359160ef43faefcda25186ffe0 | |
parent | 194d99c7e3ce54a8c7d8adf79fb1d8ad49a9bf9f (diff) |
cpufreq: Lock CPU online/offline in cpufreq_register_driver()
To protect against races with concurrent CPU online/offline, call
get_online_cpus() before registering a cpufreq driver.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 24e4ba568e77..0f4e96ff99e8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -2471,10 +2471,14 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2471 | 2471 | ||
2472 | pr_debug("trying to register driver %s\n", driver_data->name); | 2472 | pr_debug("trying to register driver %s\n", driver_data->name); |
2473 | 2473 | ||
2474 | /* Protect against concurrent CPU online/offline. */ | ||
2475 | get_online_cpus(); | ||
2476 | |||
2474 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2477 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2475 | if (cpufreq_driver) { | 2478 | if (cpufreq_driver) { |
2476 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2479 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2477 | return -EEXIST; | 2480 | ret = -EEXIST; |
2481 | goto out; | ||
2478 | } | 2482 | } |
2479 | cpufreq_driver = driver_data; | 2483 | cpufreq_driver = driver_data; |
2480 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2484 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
@@ -2513,7 +2517,10 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2513 | register_hotcpu_notifier(&cpufreq_cpu_notifier); | 2517 | register_hotcpu_notifier(&cpufreq_cpu_notifier); |
2514 | pr_debug("driver %s up and running\n", driver_data->name); | 2518 | pr_debug("driver %s up and running\n", driver_data->name); |
2515 | 2519 | ||
2516 | return 0; | 2520 | out: |
2521 | put_online_cpus(); | ||
2522 | return ret; | ||
2523 | |||
2517 | err_if_unreg: | 2524 | err_if_unreg: |
2518 | subsys_interface_unregister(&cpufreq_interface); | 2525 | subsys_interface_unregister(&cpufreq_interface); |
2519 | err_boost_unreg: | 2526 | err_boost_unreg: |
@@ -2523,7 +2530,7 @@ err_null_driver: | |||
2523 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 2530 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
2524 | cpufreq_driver = NULL; | 2531 | cpufreq_driver = NULL; |
2525 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 2532 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
2526 | return ret; | 2533 | goto out; |
2527 | } | 2534 | } |
2528 | EXPORT_SYMBOL_GPL(cpufreq_register_driver); | 2535 | EXPORT_SYMBOL_GPL(cpufreq_register_driver); |
2529 | 2536 | ||