aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-27 07:54:08 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-27 07:54:08 -0400
commiteda3d8f5604860aae1bb9996bb5efc4213778369 (patch)
tree9d3887d2665bcc5f5abf200758794545c7b2c69b /kernel/cpu.c
parent87a9f704658a40940e740b1d73d861667e9164d3 (diff)
parent8be1a6d6c77ab4532e4476fdb8177030ef48b52c (diff)
Merge commit 'upstream/master'
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index cfb1d43ab801..10ba5f1004a5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -64,6 +64,8 @@ void __init cpu_hotplug_init(void)
64 cpu_hotplug.refcount = 0; 64 cpu_hotplug.refcount = 0;
65} 65}
66 66
67cpumask_t cpu_active_map;
68
67#ifdef CONFIG_HOTPLUG_CPU 69#ifdef CONFIG_HOTPLUG_CPU
68 70
69void get_online_cpus(void) 71void get_online_cpus(void)
@@ -283,6 +285,11 @@ out_allowed:
283 set_cpus_allowed_ptr(current, &old_allowed); 285 set_cpus_allowed_ptr(current, &old_allowed);
284out_release: 286out_release:
285 cpu_hotplug_done(); 287 cpu_hotplug_done();
288 if (!err) {
289 if (raw_notifier_call_chain(&cpu_chain, CPU_POST_DEAD | mod,
290 hcpu) == NOTIFY_BAD)
291 BUG();
292 }
286 return err; 293 return err;
287} 294}
288 295
@@ -291,11 +298,30 @@ int __ref cpu_down(unsigned int cpu)
291 int err = 0; 298 int err = 0;
292 299
293 cpu_maps_update_begin(); 300 cpu_maps_update_begin();
294 if (cpu_hotplug_disabled) 301
302 if (cpu_hotplug_disabled) {
295 err = -EBUSY; 303 err = -EBUSY;
296 else 304 goto out;
297 err = _cpu_down(cpu, 0); 305 }
306
307 cpu_clear(cpu, cpu_active_map);
308
309 /*
310 * Make sure the all cpus did the reschedule and are not
311 * using stale version of the cpu_active_map.
312 * This is not strictly necessary becuase stop_machine()
313 * that we run down the line already provides the required
314 * synchronization. But it's really a side effect and we do not
315 * want to depend on the innards of the stop_machine here.
316 */
317 synchronize_sched();
318
319 err = _cpu_down(cpu, 0);
320
321 if (cpu_online(cpu))
322 cpu_set(cpu, cpu_active_map);
298 323
324out:
299 cpu_maps_update_done(); 325 cpu_maps_update_done();
300 return err; 326 return err;
301} 327}
@@ -355,11 +381,18 @@ int __cpuinit cpu_up(unsigned int cpu)
355 } 381 }
356 382
357 cpu_maps_update_begin(); 383 cpu_maps_update_begin();
358 if (cpu_hotplug_disabled) 384
385 if (cpu_hotplug_disabled) {
359 err = -EBUSY; 386 err = -EBUSY;
360 else 387 goto out;
361 err = _cpu_up(cpu, 0); 388 }
389
390 err = _cpu_up(cpu, 0);
362 391
392 if (cpu_online(cpu))
393 cpu_set(cpu, cpu_active_map);
394
395out:
363 cpu_maps_update_done(); 396 cpu_maps_update_done();
364 return err; 397 return err;
365} 398}
@@ -413,7 +446,7 @@ void __ref enable_nonboot_cpus(void)
413 goto out; 446 goto out;
414 447
415 printk("Enabling non-boot CPUs ...\n"); 448 printk("Enabling non-boot CPUs ...\n");
416 for_each_cpu_mask(cpu, frozen_cpus) { 449 for_each_cpu_mask_nr(cpu, frozen_cpus) {
417 error = _cpu_up(cpu, 1); 450 error = _cpu_up(cpu, 1);
418 if (!error) { 451 if (!error) {
419 printk("CPU%d is up\n", cpu); 452 printk("CPU%d is up\n", cpu);