aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Zimmer <nzimmer@sgi.com>2013-04-04 10:53:25 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-10 07:19:26 -0400
commit5800043b2488a1c4c6e859af860644d37419d58b (patch)
tree87e64e06920fa4483c01363d5b8d59928b0082e5
parent6eb1c377423572374518f5be93214d139d113090 (diff)
cpufreq: convert cpufreq_driver to using RCU
We eventually would like to remove the rwlock cpufreq_driver_lock or convert it back to a spinlock and protect the read sections with RCU. The first step in that direction is to make cpufreq_driver use RCU. I don't see an easy wasy to protect the cpufreq_cpu_data structure with RCU, so I am leaving it with the rwlock for now since under certain configs __cpufreq_cpu_get is a hot spot with 256+ cores. [rjw: Subject, changelog, white space] Signed-off-by: Nathan Zimmer <nzimmer@sgi.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/cpufreq.c275
1 files changed, 208 insertions, 67 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0198cd0a60ce..fd97a620518d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -39,7 +39,7 @@
39 * level driver of CPUFreq support, and its spinlock. This lock 39 * level driver of CPUFreq support, and its spinlock. This lock
40 * also protects the cpufreq_cpu_data array. 40 * also protects the cpufreq_cpu_data array.
41 */ 41 */
42static struct cpufreq_driver *cpufreq_driver; 42static struct cpufreq_driver __rcu *cpufreq_driver;
43static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); 43static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
44#ifdef CONFIG_HOTPLUG_CPU 44#ifdef CONFIG_HOTPLUG_CPU
45/* This one keeps track of the previously set governor of a removed CPU */ 45/* This one keeps track of the previously set governor of a removed CPU */
@@ -130,26 +130,34 @@ static DEFINE_MUTEX(cpufreq_governor_mutex);
130 130
131bool have_governor_per_policy(void) 131bool have_governor_per_policy(void)
132{ 132{
133 return cpufreq_driver->have_governor_per_policy; 133 bool have_governor_per_policy;
134 rcu_read_lock();
135 have_governor_per_policy =
136 rcu_dereference(cpufreq_driver)->have_governor_per_policy;
137 rcu_read_unlock();
138 return have_governor_per_policy;
134} 139}
135 140
136static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) 141static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
137{ 142{
138 struct cpufreq_policy *data; 143 struct cpufreq_policy *data;
144 struct cpufreq_driver *driver;
139 unsigned long flags; 145 unsigned long flags;
140 146
141 if (cpu >= nr_cpu_ids) 147 if (cpu >= nr_cpu_ids)
142 goto err_out; 148 goto err_out;
143 149
144 /* get the cpufreq driver */ 150 /* get the cpufreq driver */
145 read_lock_irqsave(&cpufreq_driver_lock, flags); 151 rcu_read_lock();
152 driver = rcu_dereference(cpufreq_driver);
146 153
147 if (!cpufreq_driver) 154 if (!driver)
148 goto err_out_unlock; 155 goto err_out_unlock;
149 156
150 if (!try_module_get(cpufreq_driver->owner)) 157 if (!try_module_get(driver->owner))
151 goto err_out_unlock; 158 goto err_out_unlock;
152 159
160 read_lock_irqsave(&cpufreq_driver_lock, flags);
153 161
154 /* get the CPU */ 162 /* get the CPU */
155 data = per_cpu(cpufreq_cpu_data, cpu); 163 data = per_cpu(cpufreq_cpu_data, cpu);
@@ -161,12 +169,14 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
161 goto err_out_put_module; 169 goto err_out_put_module;
162 170
163 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 171 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
172 rcu_read_unlock();
164 return data; 173 return data;
165 174
166err_out_put_module: 175err_out_put_module:
167 module_put(cpufreq_driver->owner); 176 module_put(driver->owner);
168err_out_unlock:
169 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 177 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
178err_out_unlock:
179 rcu_read_unlock();
170err_out: 180err_out:
171 return NULL; 181 return NULL;
172} 182}
@@ -189,7 +199,9 @@ static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
189{ 199{
190 if (!sysfs) 200 if (!sysfs)
191 kobject_put(&data->kobj); 201 kobject_put(&data->kobj);
192 module_put(cpufreq_driver->owner); 202 rcu_read_lock();
203 module_put(rcu_dereference(cpufreq_driver)->owner);
204 rcu_read_unlock();
193} 205}
194 206
195void cpufreq_cpu_put(struct cpufreq_policy *data) 207void cpufreq_cpu_put(struct cpufreq_policy *data)
@@ -257,7 +269,9 @@ void __cpufreq_notify_transition(struct cpufreq_policy *policy,
257 if (cpufreq_disabled()) 269 if (cpufreq_disabled())
258 return; 270 return;
259 271
260 freqs->flags = cpufreq_driver->flags; 272 rcu_read_lock();
273 freqs->flags = rcu_dereference(cpufreq_driver)->flags;
274 rcu_read_unlock();
261 pr_debug("notification %u of frequency transition to %u kHz\n", 275 pr_debug("notification %u of frequency transition to %u kHz\n",
262 state, freqs->new); 276 state, freqs->new);
263 277
@@ -268,7 +282,7 @@ void __cpufreq_notify_transition(struct cpufreq_policy *policy,
268 * which is not equal to what the cpufreq core thinks is 282 * which is not equal to what the cpufreq core thinks is
269 * "old frequency". 283 * "old frequency".
270 */ 284 */
271 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { 285 if (!(freqs->flags & CPUFREQ_CONST_LOOPS)) {
272 if ((policy) && (policy->cpu == freqs->cpu) && 286 if ((policy) && (policy->cpu == freqs->cpu) &&
273 (policy->cur) && (policy->cur != freqs->old)) { 287 (policy->cur) && (policy->cur != freqs->old)) {
274 pr_debug("Warning: CPU frequency is" 288 pr_debug("Warning: CPU frequency is"
@@ -334,11 +348,21 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
334 struct cpufreq_governor **governor) 348 struct cpufreq_governor **governor)
335{ 349{
336 int err = -EINVAL; 350 int err = -EINVAL;
337 351 struct cpufreq_driver *driver;
338 if (!cpufreq_driver) 352 bool has_setpolicy;
353 bool has_target;
354
355 rcu_read_lock();
356 driver = rcu_dereference(cpufreq_driver);
357 if (!driver) {
358 rcu_read_unlock();
339 goto out; 359 goto out;
360 }
361 has_setpolicy = driver->setpolicy ? true : false;
362 has_target = driver->target ? true : false;
363 rcu_read_unlock();
340 364
341 if (cpufreq_driver->setpolicy) { 365 if (has_setpolicy) {
342 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { 366 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
343 *policy = CPUFREQ_POLICY_PERFORMANCE; 367 *policy = CPUFREQ_POLICY_PERFORMANCE;
344 err = 0; 368 err = 0;
@@ -347,7 +371,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
347 *policy = CPUFREQ_POLICY_POWERSAVE; 371 *policy = CPUFREQ_POLICY_POWERSAVE;
348 err = 0; 372 err = 0;
349 } 373 }
350 } else if (cpufreq_driver->target) { 374 } else if (has_target) {
351 struct cpufreq_governor *t; 375 struct cpufreq_governor *t;
352 376
353 mutex_lock(&cpufreq_governor_mutex); 377 mutex_lock(&cpufreq_governor_mutex);
@@ -498,7 +522,12 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
498 */ 522 */
499static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf) 523static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
500{ 524{
501 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name); 525 ssize_t size;
526 rcu_read_lock();
527 size = scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
528 rcu_dereference(cpufreq_driver)->name);
529 rcu_read_unlock();
530 return size;
502} 531}
503 532
504/** 533/**
@@ -510,10 +539,13 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
510 ssize_t i = 0; 539 ssize_t i = 0;
511 struct cpufreq_governor *t; 540 struct cpufreq_governor *t;
512 541
513 if (!cpufreq_driver->target) { 542 rcu_read_lock();
543 if (!rcu_dereference(cpufreq_driver)->target) {
544 rcu_read_unlock();
514 i += sprintf(buf, "performance powersave"); 545 i += sprintf(buf, "performance powersave");
515 goto out; 546 goto out;
516 } 547 }
548 rcu_read_unlock();
517 549
518 list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 550 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
519 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) 551 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
@@ -591,9 +623,15 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
591static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) 623static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
592{ 624{
593 unsigned int limit; 625 unsigned int limit;
626 int (*bios_limit)(int cpu, unsigned int *limit);
594 int ret; 627 int ret;
595 if (cpufreq_driver->bios_limit) { 628
596 ret = cpufreq_driver->bios_limit(policy->cpu, &limit); 629 rcu_read_lock();
630 bios_limit = rcu_dereference(cpufreq_driver)->bios_limit;
631 rcu_read_unlock();
632
633 if (bios_limit) {
634 ret = bios_limit(policy->cpu, &limit);
597 if (!ret) 635 if (!ret)
598 return sprintf(buf, "%u\n", limit); 636 return sprintf(buf, "%u\n", limit);
599 } 637 }
@@ -736,6 +774,7 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
736{ 774{
737 struct cpufreq_policy new_policy; 775 struct cpufreq_policy new_policy;
738 struct freq_attr **drv_attr; 776 struct freq_attr **drv_attr;
777 struct cpufreq_driver *driver;
739 unsigned long flags; 778 unsigned long flags;
740 int ret = 0; 779 int ret = 0;
741 unsigned int j; 780 unsigned int j;
@@ -747,28 +786,31 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
747 return ret; 786 return ret;
748 787
749 /* set up files for this cpu device */ 788 /* set up files for this cpu device */
750 drv_attr = cpufreq_driver->attr; 789 rcu_read_lock();
790 driver = rcu_dereference(cpufreq_driver);
791 drv_attr = driver->attr;
751 while ((drv_attr) && (*drv_attr)) { 792 while ((drv_attr) && (*drv_attr)) {
752 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); 793 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
753 if (ret) 794 if (ret)
754 goto err_out_kobj_put; 795 goto err_out_unlock;
755 drv_attr++; 796 drv_attr++;
756 } 797 }
757 if (cpufreq_driver->get) { 798 if (driver->get) {
758 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); 799 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
759 if (ret) 800 if (ret)
760 goto err_out_kobj_put; 801 goto err_out_unlock;
761 } 802 }
762 if (cpufreq_driver->target) { 803 if (driver->target) {
763 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); 804 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
764 if (ret) 805 if (ret)
765 goto err_out_kobj_put; 806 goto err_out_unlock;
766 } 807 }
767 if (cpufreq_driver->bios_limit) { 808 if (driver->bios_limit) {
768 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); 809 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
769 if (ret) 810 if (ret)
770 goto err_out_kobj_put; 811 goto err_out_unlock;
771 } 812 }
813 rcu_read_unlock();
772 814
773 write_lock_irqsave(&cpufreq_driver_lock, flags); 815 write_lock_irqsave(&cpufreq_driver_lock, flags);
774 for_each_cpu(j, policy->cpus) { 816 for_each_cpu(j, policy->cpus) {
@@ -791,12 +833,20 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
791 policy->user_policy.governor = policy->governor; 833 policy->user_policy.governor = policy->governor;
792 834
793 if (ret) { 835 if (ret) {
836 int (*exit)(struct cpufreq_policy *policy);
837
794 pr_debug("setting policy failed\n"); 838 pr_debug("setting policy failed\n");
795 if (cpufreq_driver->exit) 839 rcu_read_lock();
796 cpufreq_driver->exit(policy); 840 exit = rcu_dereference(cpufreq_driver)->exit;
841 rcu_read_unlock();
842 if (exit)
843 exit(policy);
844
797 } 845 }
798 return ret; 846 return ret;
799 847
848err_out_unlock:
849 rcu_read_unlock();
800err_out_kobj_put: 850err_out_kobj_put:
801 kobject_put(&policy->kobj); 851 kobject_put(&policy->kobj);
802 wait_for_completion(&policy->kobj_unregister); 852 wait_for_completion(&policy->kobj_unregister);
@@ -854,6 +904,8 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
854 unsigned int j, cpu = dev->id; 904 unsigned int j, cpu = dev->id;
855 int ret = -ENOMEM; 905 int ret = -ENOMEM;
856 struct cpufreq_policy *policy; 906 struct cpufreq_policy *policy;
907 struct cpufreq_driver *driver;
908 int (*init)(struct cpufreq_policy *policy);
857 unsigned long flags; 909 unsigned long flags;
858#ifdef CONFIG_HOTPLUG_CPU 910#ifdef CONFIG_HOTPLUG_CPU
859 struct cpufreq_governor *gov; 911 struct cpufreq_governor *gov;
@@ -888,10 +940,15 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
888#endif 940#endif
889#endif 941#endif
890 942
891 if (!try_module_get(cpufreq_driver->owner)) { 943 rcu_read_lock();
944 driver = rcu_dereference(cpufreq_driver);
945 if (!try_module_get(driver->owner)) {
946 rcu_read_unlock();
892 ret = -EINVAL; 947 ret = -EINVAL;
893 goto module_out; 948 goto module_out;
894 } 949 }
950 init = driver->init;
951 rcu_read_unlock();
895 952
896 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); 953 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
897 if (!policy) 954 if (!policy)
@@ -916,7 +973,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
916 /* call driver. From then on the cpufreq must be able 973 /* call driver. From then on the cpufreq must be able
917 * to accept all calls to ->verify and ->setpolicy for this CPU 974 * to accept all calls to ->verify and ->setpolicy for this CPU
918 */ 975 */
919 ret = cpufreq_driver->init(policy); 976 ret = init(policy);
920 if (ret) { 977 if (ret) {
921 pr_debug("initialization failed\n"); 978 pr_debug("initialization failed\n");
922 goto err_set_policy_cpu; 979 goto err_set_policy_cpu;
@@ -951,7 +1008,9 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
951 goto err_out_unregister; 1008 goto err_out_unregister;
952 1009
953 kobject_uevent(&policy->kobj, KOBJ_ADD); 1010 kobject_uevent(&policy->kobj, KOBJ_ADD);
954 module_put(cpufreq_driver->owner); 1011 rcu_read_lock();
1012 module_put(rcu_dereference(cpufreq_driver)->owner);
1013 rcu_read_unlock();
955 pr_debug("initialization complete\n"); 1014 pr_debug("initialization complete\n");
956 1015
957 return 0; 1016 return 0;
@@ -973,7 +1032,9 @@ err_free_cpumask:
973err_free_policy: 1032err_free_policy:
974 kfree(policy); 1033 kfree(policy);
975nomem_out: 1034nomem_out:
976 module_put(cpufreq_driver->owner); 1035 rcu_read_lock();
1036 module_put(rcu_dereference(cpufreq_driver)->owner);
1037 rcu_read_unlock();
977module_out: 1038module_out:
978 return ret; 1039 return ret;
979} 1040}
@@ -1007,9 +1068,12 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
1007 unsigned int cpu = dev->id, ret, cpus; 1068 unsigned int cpu = dev->id, ret, cpus;
1008 unsigned long flags; 1069 unsigned long flags;
1009 struct cpufreq_policy *data; 1070 struct cpufreq_policy *data;
1071 struct cpufreq_driver *driver;
1010 struct kobject *kobj; 1072 struct kobject *kobj;
1011 struct completion *cmp; 1073 struct completion *cmp;
1012 struct device *cpu_dev; 1074 struct device *cpu_dev;
1075 bool has_target;
1076 int (*exit)(struct cpufreq_policy *policy);
1013 1077
1014 pr_debug("%s: unregistering CPU %u\n", __func__, cpu); 1078 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
1015 1079
@@ -1025,14 +1089,19 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
1025 return -EINVAL; 1089 return -EINVAL;
1026 } 1090 }
1027 1091
1028 if (cpufreq_driver->target) 1092 rcu_read_lock();
1093 driver = rcu_dereference(cpufreq_driver);
1094 has_target = driver->target ? true : false;
1095 exit = driver->exit;
1096 if (has_target)
1029 __cpufreq_governor(data, CPUFREQ_GOV_STOP); 1097 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1030 1098
1031#ifdef CONFIG_HOTPLUG_CPU 1099#ifdef CONFIG_HOTPLUG_CPU
1032 if (!cpufreq_driver->setpolicy) 1100 if (!driver->setpolicy)
1033 strncpy(per_cpu(cpufreq_cpu_governor, cpu), 1101 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1034 data->governor->name, CPUFREQ_NAME_LEN); 1102 data->governor->name, CPUFREQ_NAME_LEN);
1035#endif 1103#endif
1104 rcu_read_unlock();
1036 1105
1037 WARN_ON(lock_policy_rwsem_write(cpu)); 1106 WARN_ON(lock_policy_rwsem_write(cpu));
1038 cpus = cpumask_weight(data->cpus); 1107 cpus = cpumask_weight(data->cpus);
@@ -1091,13 +1160,13 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
1091 wait_for_completion(cmp); 1160 wait_for_completion(cmp);
1092 pr_debug("wait complete\n"); 1161 pr_debug("wait complete\n");
1093 1162
1094 if (cpufreq_driver->exit) 1163 if (exit)
1095 cpufreq_driver->exit(data); 1164 exit(data);
1096 1165
1097 free_cpumask_var(data->related_cpus); 1166 free_cpumask_var(data->related_cpus);
1098 free_cpumask_var(data->cpus); 1167 free_cpumask_var(data->cpus);
1099 kfree(data); 1168 kfree(data);
1100 } else if (cpufreq_driver->target) { 1169 } else if (has_target) {
1101 __cpufreq_governor(data, CPUFREQ_GOV_START); 1170 __cpufreq_governor(data, CPUFREQ_GOV_START);
1102 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); 1171 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1103 } 1172 }
@@ -1171,10 +1240,18 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1171unsigned int cpufreq_quick_get(unsigned int cpu) 1240unsigned int cpufreq_quick_get(unsigned int cpu)
1172{ 1241{
1173 struct cpufreq_policy *policy; 1242 struct cpufreq_policy *policy;
1243 struct cpufreq_driver *driver;
1244 unsigned int (*get)(unsigned int cpu);
1174 unsigned int ret_freq = 0; 1245 unsigned int ret_freq = 0;
1175 1246
1176 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) 1247 rcu_read_lock();
1177 return cpufreq_driver->get(cpu); 1248 driver = rcu_dereference(cpufreq_driver);
1249 if (driver && driver->setpolicy && driver->get) {
1250 get = driver->get;
1251 rcu_read_unlock();
1252 return get(cpu);
1253 }
1254 rcu_read_unlock();
1178 1255
1179 policy = cpufreq_cpu_get(cpu); 1256 policy = cpufreq_cpu_get(cpu);
1180 if (policy) { 1257 if (policy) {
@@ -1210,15 +1287,26 @@ EXPORT_SYMBOL(cpufreq_quick_get_max);
1210static unsigned int __cpufreq_get(unsigned int cpu) 1287static unsigned int __cpufreq_get(unsigned int cpu)
1211{ 1288{
1212 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); 1289 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
1290 struct cpufreq_driver *driver;
1291 unsigned int (*get)(unsigned int cpu);
1213 unsigned int ret_freq = 0; 1292 unsigned int ret_freq = 0;
1293 u8 flags;
1294
1214 1295
1215 if (!cpufreq_driver->get) 1296 rcu_read_lock();
1297 driver = rcu_dereference(cpufreq_driver);
1298 if (!driver->get) {
1299 rcu_read_unlock();
1216 return ret_freq; 1300 return ret_freq;
1301 }
1302 flags = driver->flags;
1303 get = driver->get;
1304 rcu_read_unlock();
1217 1305
1218 ret_freq = cpufreq_driver->get(cpu); 1306 ret_freq = get(cpu);
1219 1307
1220 if (ret_freq && policy->cur && 1308 if (ret_freq && policy->cur &&
1221 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { 1309 !(flags & CPUFREQ_CONST_LOOPS)) {
1222 /* verify no discrepancy between actual and 1310 /* verify no discrepancy between actual and
1223 saved value exists */ 1311 saved value exists */
1224 if (unlikely(ret_freq != policy->cur)) { 1312 if (unlikely(ret_freq != policy->cur)) {
@@ -1274,6 +1362,7 @@ static struct subsys_interface cpufreq_interface = {
1274 */ 1362 */
1275static int cpufreq_bp_suspend(void) 1363static int cpufreq_bp_suspend(void)
1276{ 1364{
1365 int (*suspend)(struct cpufreq_policy *policy);
1277 int ret = 0; 1366 int ret = 0;
1278 1367
1279 int cpu = smp_processor_id(); 1368 int cpu = smp_processor_id();
@@ -1286,8 +1375,11 @@ static int cpufreq_bp_suspend(void)
1286 if (!cpu_policy) 1375 if (!cpu_policy)
1287 return 0; 1376 return 0;
1288 1377
1289 if (cpufreq_driver->suspend) { 1378 rcu_read_lock();
1290 ret = cpufreq_driver->suspend(cpu_policy); 1379 suspend = rcu_dereference(cpufreq_driver)->suspend;
1380 rcu_read_unlock();
1381 if (suspend) {
1382 ret = suspend(cpu_policy);
1291 if (ret) 1383 if (ret)
1292 printk(KERN_ERR "cpufreq: suspend failed in ->suspend " 1384 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1293 "step on CPU %u\n", cpu_policy->cpu); 1385 "step on CPU %u\n", cpu_policy->cpu);
@@ -1313,6 +1405,7 @@ static int cpufreq_bp_suspend(void)
1313static void cpufreq_bp_resume(void) 1405static void cpufreq_bp_resume(void)
1314{ 1406{
1315 int ret = 0; 1407 int ret = 0;
1408 int (*resume)(struct cpufreq_policy *policy);
1316 1409
1317 int cpu = smp_processor_id(); 1410 int cpu = smp_processor_id();
1318 struct cpufreq_policy *cpu_policy; 1411 struct cpufreq_policy *cpu_policy;
@@ -1324,8 +1417,12 @@ static void cpufreq_bp_resume(void)
1324 if (!cpu_policy) 1417 if (!cpu_policy)
1325 return; 1418 return;
1326 1419
1327 if (cpufreq_driver->resume) { 1420 rcu_read_lock();
1328 ret = cpufreq_driver->resume(cpu_policy); 1421 resume = rcu_dereference(cpufreq_driver)->resume;
1422 rcu_read_unlock();
1423
1424 if (resume) {
1425 ret = resume(cpu_policy);
1329 if (ret) { 1426 if (ret) {
1330 printk(KERN_ERR "cpufreq: resume failed in ->resume " 1427 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1331 "step on CPU %u\n", cpu_policy->cpu); 1428 "step on CPU %u\n", cpu_policy->cpu);
@@ -1352,10 +1449,14 @@ static struct syscore_ops cpufreq_syscore_ops = {
1352 */ 1449 */
1353const char *cpufreq_get_current_driver(void) 1450const char *cpufreq_get_current_driver(void)
1354{ 1451{
1355 if (cpufreq_driver) 1452 struct cpufreq_driver *driver;
1356 return cpufreq_driver->name; 1453 const char *name = NULL;
1357 1454 rcu_read_lock();
1358 return NULL; 1455 driver = rcu_dereference(cpufreq_driver);
1456 if (driver)
1457 name = driver->name;
1458 rcu_read_unlock();
1459 return name;
1359} 1460}
1360EXPORT_SYMBOL_GPL(cpufreq_get_current_driver); 1461EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
1361 1462
@@ -1449,6 +1550,9 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1449{ 1550{
1450 int retval = -EINVAL; 1551 int retval = -EINVAL;
1451 unsigned int old_target_freq = target_freq; 1552 unsigned int old_target_freq = target_freq;
1553 int (*target)(struct cpufreq_policy *policy,
1554 unsigned int target_freq,
1555 unsigned int relation);
1452 1556
1453 if (cpufreq_disabled()) 1557 if (cpufreq_disabled())
1454 return -ENODEV; 1558 return -ENODEV;
@@ -1465,8 +1569,11 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1465 if (target_freq == policy->cur) 1569 if (target_freq == policy->cur)
1466 return 0; 1570 return 0;
1467 1571
1468 if (cpufreq_driver->target) 1572 rcu_read_lock();
1469 retval = cpufreq_driver->target(policy, target_freq, relation); 1573 target = rcu_dereference(cpufreq_driver)->target;
1574 rcu_read_unlock();
1575 if (target)
1576 retval = target(policy, target_freq, relation);
1470 1577
1471 return retval; 1578 return retval;
1472} 1579}
@@ -1499,18 +1606,24 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1499int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) 1606int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
1500{ 1607{
1501 int ret = 0; 1608 int ret = 0;
1609 unsigned int (*getavg)(struct cpufreq_policy *policy,
1610 unsigned int cpu);
1502 1611
1503 if (cpufreq_disabled()) 1612 if (cpufreq_disabled())
1504 return ret; 1613 return ret;
1505 1614
1506 if (!cpufreq_driver->getavg) 1615 rcu_read_lock();
1616 getavg = rcu_dereference(cpufreq_driver)->getavg;
1617 rcu_read_unlock();
1618
1619 if (!getavg)
1507 return 0; 1620 return 0;
1508 1621
1509 policy = cpufreq_cpu_get(policy->cpu); 1622 policy = cpufreq_cpu_get(policy->cpu);
1510 if (!policy) 1623 if (!policy)
1511 return -EINVAL; 1624 return -EINVAL;
1512 1625
1513 ret = cpufreq_driver->getavg(policy, cpu); 1626 ret = getavg(policy, cpu);
1514 1627
1515 cpufreq_cpu_put(policy); 1628 cpufreq_cpu_put(policy);
1516 return ret; 1629 return ret;
@@ -1668,6 +1781,9 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
1668 struct cpufreq_policy *policy) 1781 struct cpufreq_policy *policy)
1669{ 1782{
1670 int ret = 0, failed = 1; 1783 int ret = 0, failed = 1;
1784 struct cpufreq_driver *driver;
1785 int (*verify)(struct cpufreq_policy *policy);
1786 int (*setpolicy)(struct cpufreq_policy *policy);
1671 1787
1672 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, 1788 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
1673 policy->min, policy->max); 1789 policy->min, policy->max);
@@ -1681,7 +1797,13 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
1681 } 1797 }
1682 1798
1683 /* verify the cpu speed can be set within this limit */ 1799 /* verify the cpu speed can be set within this limit */
1684 ret = cpufreq_driver->verify(policy); 1800 rcu_read_lock();
1801 driver = rcu_dereference(cpufreq_driver);
1802 verify = driver->verify;
1803 setpolicy = driver->setpolicy;
1804 rcu_read_unlock();
1805
1806 ret = verify(policy);
1685 if (ret) 1807 if (ret)
1686 goto error_out; 1808 goto error_out;
1687 1809
@@ -1695,7 +1817,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
1695 1817
1696 /* verify the cpu speed can be set within this limit, 1818 /* verify the cpu speed can be set within this limit,
1697 which might be different to the first one */ 1819 which might be different to the first one */
1698 ret = cpufreq_driver->verify(policy); 1820 ret = verify(policy);
1699 if (ret) 1821 if (ret)
1700 goto error_out; 1822 goto error_out;
1701 1823
@@ -1709,10 +1831,10 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
1709 pr_debug("new min and max freqs are %u - %u kHz\n", 1831 pr_debug("new min and max freqs are %u - %u kHz\n",
1710 data->min, data->max); 1832 data->min, data->max);
1711 1833
1712 if (cpufreq_driver->setpolicy) { 1834 if (setpolicy) {
1713 data->policy = policy->policy; 1835 data->policy = policy->policy;
1714 pr_debug("setting range\n"); 1836 pr_debug("setting range\n");
1715 ret = cpufreq_driver->setpolicy(policy); 1837 ret = setpolicy(policy);
1716 } else { 1838 } else {
1717 if (policy->governor != data->governor) { 1839 if (policy->governor != data->governor) {
1718 /* save old, working values */ 1840 /* save old, working values */
@@ -1772,6 +1894,11 @@ int cpufreq_update_policy(unsigned int cpu)
1772{ 1894{
1773 struct cpufreq_policy *data = cpufreq_cpu_get(cpu); 1895 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1774 struct cpufreq_policy policy; 1896 struct cpufreq_policy policy;
1897 struct cpufreq_driver *driver;
1898 unsigned int (*get)(unsigned int cpu);
1899 int (*target)(struct cpufreq_policy *policy,
1900 unsigned int target_freq,
1901 unsigned int relation);
1775 int ret; 1902 int ret;
1776 1903
1777 if (!data) { 1904 if (!data) {
@@ -1793,13 +1920,18 @@ int cpufreq_update_policy(unsigned int cpu)
1793 1920
1794 /* BIOS might change freq behind our back 1921 /* BIOS might change freq behind our back
1795 -> ask driver for current freq and notify governors about a change */ 1922 -> ask driver for current freq and notify governors about a change */
1796 if (cpufreq_driver->get) { 1923 rcu_read_lock();
1797 policy.cur = cpufreq_driver->get(cpu); 1924 driver = rcu_access_pointer(cpufreq_driver);
1925 get = driver->get;
1926 target = driver->target;
1927 rcu_read_unlock();
1928 if (get) {
1929 policy.cur = get(cpu);
1798 if (!data->cur) { 1930 if (!data->cur) {
1799 pr_debug("Driver did not initialize current freq"); 1931 pr_debug("Driver did not initialize current freq");
1800 data->cur = policy.cur; 1932 data->cur = policy.cur;
1801 } else { 1933 } else {
1802 if (data->cur != policy.cur && cpufreq_driver->target) 1934 if (data->cur != policy.cur && target)
1803 cpufreq_out_of_sync(cpu, data->cur, 1935 cpufreq_out_of_sync(cpu, data->cur,
1804 policy.cur); 1936 policy.cur);
1805 } 1937 }
@@ -1878,18 +2010,19 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
1878 driver_data->flags |= CPUFREQ_CONST_LOOPS; 2010 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1879 2011
1880 write_lock_irqsave(&cpufreq_driver_lock, flags); 2012 write_lock_irqsave(&cpufreq_driver_lock, flags);
1881 if (cpufreq_driver) { 2013 if (rcu_access_pointer(cpufreq_driver)) {
1882 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2014 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1883 return -EBUSY; 2015 return -EBUSY;
1884 } 2016 }
1885 cpufreq_driver = driver_data; 2017 rcu_assign_pointer(cpufreq_driver, driver_data);
1886 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2018 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2019 synchronize_rcu();
1887 2020
1888 ret = subsys_interface_register(&cpufreq_interface); 2021 ret = subsys_interface_register(&cpufreq_interface);
1889 if (ret) 2022 if (ret)
1890 goto err_null_driver; 2023 goto err_null_driver;
1891 2024
1892 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { 2025 if (!(driver_data->flags & CPUFREQ_STICKY)) {
1893 int i; 2026 int i;
1894 ret = -ENODEV; 2027 ret = -ENODEV;
1895 2028
@@ -1916,8 +2049,9 @@ err_if_unreg:
1916 subsys_interface_unregister(&cpufreq_interface); 2049 subsys_interface_unregister(&cpufreq_interface);
1917err_null_driver: 2050err_null_driver:
1918 write_lock_irqsave(&cpufreq_driver_lock, flags); 2051 write_lock_irqsave(&cpufreq_driver_lock, flags);
1919 cpufreq_driver = NULL; 2052 rcu_assign_pointer(cpufreq_driver, NULL);
1920 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2053 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2054 synchronize_rcu();
1921 return ret; 2055 return ret;
1922} 2056}
1923EXPORT_SYMBOL_GPL(cpufreq_register_driver); 2057EXPORT_SYMBOL_GPL(cpufreq_register_driver);
@@ -1934,9 +2068,15 @@ EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1934int cpufreq_unregister_driver(struct cpufreq_driver *driver) 2068int cpufreq_unregister_driver(struct cpufreq_driver *driver)
1935{ 2069{
1936 unsigned long flags; 2070 unsigned long flags;
2071 struct cpufreq_driver *old_driver;
1937 2072
1938 if (!cpufreq_driver || (driver != cpufreq_driver)) 2073 rcu_read_lock();
2074 old_driver = rcu_access_pointer(cpufreq_driver);
2075 if (!old_driver || (driver != old_driver)) {
2076 rcu_read_unlock();
1939 return -EINVAL; 2077 return -EINVAL;
2078 }
2079 rcu_read_unlock();
1940 2080
1941 pr_debug("unregistering driver %s\n", driver->name); 2081 pr_debug("unregistering driver %s\n", driver->name);
1942 2082
@@ -1944,8 +2084,9 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
1944 unregister_hotcpu_notifier(&cpufreq_cpu_notifier); 2084 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
1945 2085
1946 write_lock_irqsave(&cpufreq_driver_lock, flags); 2086 write_lock_irqsave(&cpufreq_driver_lock, flags);
1947 cpufreq_driver = NULL; 2087 rcu_assign_pointer(cpufreq_driver, NULL);
1948 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2088 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2089 synchronize_rcu();
1949 2090
1950 return 0; 2091 return 0;
1951} 2092}