diff options
-rw-r--r-- | kernel/cpu.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 124ad9d6be16..09207c772c25 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -134,6 +134,26 @@ int __ref register_cpu_notifier(struct notifier_block *nb) | |||
134 | return ret; | 134 | return ret; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int __cpu_notify(unsigned long val, void *v, int nr_to_call, | ||
138 | int *nr_calls) | ||
139 | { | ||
140 | return __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call, | ||
141 | nr_calls); | ||
142 | } | ||
143 | |||
144 | static int cpu_notify(unsigned long val, void *v) | ||
145 | { | ||
146 | return __cpu_notify(val, v, -1, NULL); | ||
147 | } | ||
148 | |||
149 | static void cpu_notify_nofail(unsigned long val, void *v) | ||
150 | { | ||
151 | int err; | ||
152 | |||
153 | err = cpu_notify(val, v); | ||
154 | BUG_ON(err == NOTIFY_BAD); | ||
155 | } | ||
156 | |||
137 | #ifdef CONFIG_HOTPLUG_CPU | 157 | #ifdef CONFIG_HOTPLUG_CPU |
138 | 158 | ||
139 | EXPORT_SYMBOL(register_cpu_notifier); | 159 | EXPORT_SYMBOL(register_cpu_notifier); |
@@ -181,8 +201,7 @@ static int __ref take_cpu_down(void *_param) | |||
181 | if (err < 0) | 201 | if (err < 0) |
182 | return err; | 202 | return err; |
183 | 203 | ||
184 | raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod, | 204 | cpu_notify(CPU_DYING | param->mod, param->hcpu); |
185 | param->hcpu); | ||
186 | 205 | ||
187 | if (task_cpu(param->caller) == cpu) | 206 | if (task_cpu(param->caller) == cpu) |
188 | move_task_off_dead_cpu(cpu, param->caller); | 207 | move_task_off_dead_cpu(cpu, param->caller); |
@@ -212,14 +231,12 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
212 | 231 | ||
213 | cpu_hotplug_begin(); | 232 | cpu_hotplug_begin(); |
214 | set_cpu_active(cpu, false); | 233 | set_cpu_active(cpu, false); |
215 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, | 234 | err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls); |
216 | hcpu, -1, &nr_calls); | ||
217 | if (err == NOTIFY_BAD) { | 235 | if (err == NOTIFY_BAD) { |
218 | set_cpu_active(cpu, true); | 236 | set_cpu_active(cpu, true); |
219 | 237 | ||
220 | nr_calls--; | 238 | nr_calls--; |
221 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, | 239 | __cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL); |
222 | hcpu, nr_calls, NULL); | ||
223 | printk("%s: attempt to take down CPU %u failed\n", | 240 | printk("%s: attempt to take down CPU %u failed\n", |
224 | __func__, cpu); | 241 | __func__, cpu); |
225 | err = -EINVAL; | 242 | err = -EINVAL; |
@@ -230,9 +247,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
230 | if (err) { | 247 | if (err) { |
231 | set_cpu_active(cpu, true); | 248 | set_cpu_active(cpu, true); |
232 | /* CPU didn't die: tell everyone. Can't complain. */ | 249 | /* CPU didn't die: tell everyone. Can't complain. */ |
233 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, | 250 | cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); |
234 | hcpu) == NOTIFY_BAD) | ||
235 | BUG(); | ||
236 | 251 | ||
237 | goto out_release; | 252 | goto out_release; |
238 | } | 253 | } |
@@ -246,19 +261,14 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
246 | __cpu_die(cpu); | 261 | __cpu_die(cpu); |
247 | 262 | ||
248 | /* CPU is completely dead: tell everyone. Too late to complain. */ | 263 | /* CPU is completely dead: tell everyone. Too late to complain. */ |
249 | if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod, | 264 | cpu_notify_nofail(CPU_DEAD | mod, hcpu); |
250 | hcpu) == NOTIFY_BAD) | ||
251 | BUG(); | ||
252 | 265 | ||
253 | check_for_tasks(cpu); | 266 | check_for_tasks(cpu); |
254 | 267 | ||
255 | out_release: | 268 | out_release: |
256 | cpu_hotplug_done(); | 269 | cpu_hotplug_done(); |
257 | if (!err) { | 270 | if (!err) |
258 | if (raw_notifier_call_chain(&cpu_chain, CPU_POST_DEAD | mod, | 271 | cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu); |
259 | hcpu) == NOTIFY_BAD) | ||
260 | BUG(); | ||
261 | } | ||
262 | return err; | 272 | return err; |
263 | } | 273 | } |
264 | 274 | ||
@@ -293,8 +303,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) | |||
293 | return -EINVAL; | 303 | return -EINVAL; |
294 | 304 | ||
295 | cpu_hotplug_begin(); | 305 | cpu_hotplug_begin(); |
296 | ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu, | 306 | ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls); |
297 | -1, &nr_calls); | ||
298 | if (ret == NOTIFY_BAD) { | 307 | if (ret == NOTIFY_BAD) { |
299 | nr_calls--; | 308 | nr_calls--; |
300 | printk("%s: attempt to bring up CPU %u failed\n", | 309 | printk("%s: attempt to bring up CPU %u failed\n", |
@@ -312,12 +321,11 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) | |||
312 | set_cpu_active(cpu, true); | 321 | set_cpu_active(cpu, true); |
313 | 322 | ||
314 | /* Now call notifier in preparation. */ | 323 | /* Now call notifier in preparation. */ |
315 | raw_notifier_call_chain(&cpu_chain, CPU_ONLINE | mod, hcpu); | 324 | cpu_notify(CPU_ONLINE | mod, hcpu); |
316 | 325 | ||
317 | out_notify: | 326 | out_notify: |
318 | if (ret != 0) | 327 | if (ret != 0) |
319 | __raw_notifier_call_chain(&cpu_chain, | 328 | __cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL); |
320 | CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL); | ||
321 | cpu_hotplug_done(); | 329 | cpu_hotplug_done(); |
322 | 330 | ||
323 | return ret; | 331 | return ret; |
@@ -481,7 +489,7 @@ void __cpuinit notify_cpu_starting(unsigned int cpu) | |||
481 | if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus)) | 489 | if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus)) |
482 | val = CPU_STARTING_FROZEN; | 490 | val = CPU_STARTING_FROZEN; |
483 | #endif /* CONFIG_PM_SLEEP_SMP */ | 491 | #endif /* CONFIG_PM_SLEEP_SMP */ |
484 | raw_notifier_call_chain(&cpu_chain, val, (void *)(long)cpu); | 492 | cpu_notify(val, (void *)(long)cpu); |
485 | } | 493 | } |
486 | 494 | ||
487 | #endif /* CONFIG_SMP */ | 495 | #endif /* CONFIG_SMP */ |