aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
authorMax Krasnyansky <maxk@qualcomm.com>2008-07-15 07:43:49 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 07:22:25 -0400
commite761b7725234276a802322549cee5255305a0930 (patch)
tree27b351a7d5fc9a93590e0effce1c5adb1bfcebc0 /kernel/cpu.c
parent7ebefa8ceefed44cc321be70afc54a585a68ac0b (diff)
cpu hotplug, sched: Introduce cpu_active_map and redo sched domain managment (take 2)
This is based on Linus' idea of creating cpu_active_map that prevents scheduler load balancer from migrating tasks to the cpu that is going down. It allows us to simplify domain management code and avoid unecessary domain rebuilds during cpu hotplug event handling. Please ignore the cpusets part for now. It needs some more work in order to avoid crazy lock nesting. Although I did simplfy and unify domain reinitialization logic. We now simply call partition_sched_domains() in all the cases. This means that we're using exact same code paths as in cpusets case and hence the test below cover cpusets too. Cpuset changes to make rebuild_sched_domains() callable from various contexts are in the separate patch (right next after this one). This not only boots but also easily handles while true; do make clean; make -j 8; done and while true; do on-off-cpu 1; done at the same time. (on-off-cpu 1 simple does echo 0/1 > /sys/.../cpu1/online thing). Suprisingly the box (dual-core Core2) is quite usable. In fact I'm typing this on right now in gnome-terminal and things are moving just fine. Also this is running with most of the debug features enabled (lockdep, mutex, etc) no BUG_ONs or lockdep complaints so far. I believe I addressed all of the Dmitry's comments for original Linus' version. I changed both fair and rt balancer to mask out non-active cpus. And replaced cpu_is_offline() with !cpu_active() in the main scheduler code where it made sense (to me). Signed-off-by: Max Krasnyanskiy <maxk@qualcomm.com> Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Gregory Haskins <ghaskins@novell.com> Cc: dmitry.adamushko@gmail.com Cc: pj@sgi.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index cfb1d43ab801..a1ac7ea245d7 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)
@@ -291,11 +293,20 @@ int __ref cpu_down(unsigned int cpu)
291 int err = 0; 293 int err = 0;
292 294
293 cpu_maps_update_begin(); 295 cpu_maps_update_begin();
294 if (cpu_hotplug_disabled) 296
297 if (cpu_hotplug_disabled) {
295 err = -EBUSY; 298 err = -EBUSY;
296 else 299 goto out;
297 err = _cpu_down(cpu, 0); 300 }
301
302 cpu_clear(cpu, cpu_active_map);
303
304 err = _cpu_down(cpu, 0);
305
306 if (cpu_online(cpu))
307 cpu_set(cpu, cpu_active_map);
298 308
309out:
299 cpu_maps_update_done(); 310 cpu_maps_update_done();
300 return err; 311 return err;
301} 312}
@@ -355,11 +366,18 @@ int __cpuinit cpu_up(unsigned int cpu)
355 } 366 }
356 367
357 cpu_maps_update_begin(); 368 cpu_maps_update_begin();
358 if (cpu_hotplug_disabled) 369
370 if (cpu_hotplug_disabled) {
359 err = -EBUSY; 371 err = -EBUSY;
360 else 372 goto out;
361 err = _cpu_up(cpu, 0); 373 }
362 374
375 err = _cpu_up(cpu, 0);
376
377 if (cpu_online(cpu))
378 cpu_set(cpu, cpu_active_map);
379
380out:
363 cpu_maps_update_done(); 381 cpu_maps_update_done();
364 return err; 382 return err;
365} 383}