aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Krasnyansky <maxk@qualcomm.com>2008-05-29 14:17:01 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-19 03:14:51 -0400
commitf18f982abf183e91f435990d337164c7a43d1e6d (patch)
treed80f6b09825db1c5103d7b8518189613c9b57fbe
parent15a8641eadb492ef7c5489faa25256967bdfd303 (diff)
sched: CPU hotplug events must not destroy scheduler domains created by the cpusets
First issue is not related to the cpusets. We're simply leaking doms_cur. It's allocated in arch_init_sched_domains() which is called for every hotplug event. So we just keep reallocation doms_cur without freeing it. I introduced free_sched_domains() function that cleans things up. Second issue is that sched domains created by the cpusets are completely destroyed by the CPU hotplug events. For all CPU hotplug events scheduler attaches all CPUs to the NULL domain and then puts them all into the single domain thereby destroying domains created by the cpusets (partition_sched_domains). The solution is simple, when cpusets are enabled scheduler should not create default domain and instead let cpusets do that. Which is exactly what the patch does. Signed-off-by: Max Krasnyansky <maxk@qualcomm.com> Cc: pj@sgi.com Cc: menage@google.com Cc: rostedt@goodmis.org Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--kernel/cpuset.c6
-rw-r--r--kernel/sched.c22
2 files changed, 28 insertions, 0 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 039baa4cd90c..bceb89557973 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1890,6 +1890,12 @@ static void common_cpu_mem_hotplug_unplug(void)
1890 top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; 1890 top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
1891 scan_for_empty_cpusets(&top_cpuset); 1891 scan_for_empty_cpusets(&top_cpuset);
1892 1892
1893 /*
1894 * Scheduler destroys domains on hotplug events.
1895 * Rebuild them based on the current settings.
1896 */
1897 rebuild_sched_domains();
1898
1893 cgroup_unlock(); 1899 cgroup_unlock();
1894} 1900}
1895 1901
diff --git a/kernel/sched.c b/kernel/sched.c
index ce375cb551e9..4a3cb0614158 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -7238,6 +7238,18 @@ void __attribute__((weak)) arch_update_cpu_topology(void)
7238} 7238}
7239 7239
7240/* 7240/*
7241 * Free current domain masks.
7242 * Called after all cpus are attached to NULL domain.
7243 */
7244static void free_sched_domains(void)
7245{
7246 ndoms_cur = 0;
7247 if (doms_cur != &fallback_doms)
7248 kfree(doms_cur);
7249 doms_cur = &fallback_doms;
7250}
7251
7252/*
7241 * Set up scheduler domains and groups. Callers must hold the hotplug lock. 7253 * Set up scheduler domains and groups. Callers must hold the hotplug lock.
7242 * For now this just excludes isolated cpus, but could be used to 7254 * For now this just excludes isolated cpus, but could be used to
7243 * exclude other special cases in the future. 7255 * exclude other special cases in the future.
@@ -7384,6 +7396,7 @@ int arch_reinit_sched_domains(void)
7384 get_online_cpus(); 7396 get_online_cpus();
7385 mutex_lock(&sched_domains_mutex); 7397 mutex_lock(&sched_domains_mutex);
7386 detach_destroy_domains(&cpu_online_map); 7398 detach_destroy_domains(&cpu_online_map);
7399 free_sched_domains();
7387 err = arch_init_sched_domains(&cpu_online_map); 7400 err = arch_init_sched_domains(&cpu_online_map);
7388 mutex_unlock(&sched_domains_mutex); 7401 mutex_unlock(&sched_domains_mutex);
7389 put_online_cpus(); 7402 put_online_cpus();
@@ -7469,6 +7482,7 @@ static int update_sched_domains(struct notifier_block *nfb,
7469 case CPU_DOWN_PREPARE: 7482 case CPU_DOWN_PREPARE:
7470 case CPU_DOWN_PREPARE_FROZEN: 7483 case CPU_DOWN_PREPARE_FROZEN:
7471 detach_destroy_domains(&cpu_online_map); 7484 detach_destroy_domains(&cpu_online_map);
7485 free_sched_domains();
7472 return NOTIFY_OK; 7486 return NOTIFY_OK;
7473 7487
7474 case CPU_UP_CANCELED: 7488 case CPU_UP_CANCELED:
@@ -7487,8 +7501,16 @@ static int update_sched_domains(struct notifier_block *nfb,
7487 return NOTIFY_DONE; 7501 return NOTIFY_DONE;
7488 } 7502 }
7489 7503
7504#ifndef CONFIG_CPUSETS
7505 /*
7506 * Create default domain partitioning if cpusets are disabled.
7507 * Otherwise we let cpusets rebuild the domains based on the
7508 * current setup.
7509 */
7510
7490 /* The hotplug lock is already held by cpu_up/cpu_down */ 7511 /* The hotplug lock is already held by cpu_up/cpu_down */
7491 arch_init_sched_domains(&cpu_online_map); 7512 arch_init_sched_domains(&cpu_online_map);
7513#endif
7492 7514
7493 return NOTIFY_OK; 7515 return NOTIFY_OK;
7494} 7516}