aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2007-10-15 11:00:19 -0400
committerIngo Molnar <mingo@elte.hu>2007-10-15 11:00:19 -0400
commit6382bc90f5664c450afc1f896e7ddb35ba182af9 (patch)
tree01e40b9d5f44bfeed712cf8d394a16aa93598436 /kernel/sched.c
parent97b6ea7b6369d51a451a7d5747a7939a593fdd9c (diff)
sched: domain sysctl fixes: unregister the sysctl table before domains
Unregister and free the sysctl table before destroying domains, then rebuild and register after creating the new domains. This prevents the sysctl table from pointing to freed memory for root to write. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 374f42170d6d..a2dd05435534 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5250,6 +5250,18 @@ static struct ctl_table *sd_alloc_ctl_entry(int n)
5250 return entry; 5250 return entry;
5251} 5251}
5252 5252
5253static void sd_free_ctl_entry(struct ctl_table **tablep)
5254{
5255 struct ctl_table *entry = *tablep;
5256
5257 for (entry = *tablep; entry->procname; entry++)
5258 if (entry->child)
5259 sd_free_ctl_entry(&entry->child);
5260
5261 kfree(*tablep);
5262 *tablep = NULL;
5263}
5264
5253static void 5265static void
5254set_table_entry(struct ctl_table *entry, 5266set_table_entry(struct ctl_table *entry,
5255 const char *procname, void *data, int maxlen, 5267 const char *procname, void *data, int maxlen,
@@ -5318,7 +5330,7 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
5318} 5330}
5319 5331
5320static struct ctl_table_header *sd_sysctl_header; 5332static struct ctl_table_header *sd_sysctl_header;
5321static void init_sched_domain_sysctl(void) 5333static void register_sched_domain_sysctl(void)
5322{ 5334{
5323 int i, cpu_num = num_online_cpus(); 5335 int i, cpu_num = num_online_cpus();
5324 struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); 5336 struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1);
@@ -5335,8 +5347,18 @@ static void init_sched_domain_sysctl(void)
5335 } 5347 }
5336 sd_sysctl_header = register_sysctl_table(sd_ctl_root); 5348 sd_sysctl_header = register_sysctl_table(sd_ctl_root);
5337} 5349}
5350
5351static void unregister_sched_domain_sysctl(void)
5352{
5353 unregister_sysctl_table(sd_sysctl_header);
5354 sd_sysctl_header = NULL;
5355 sd_free_ctl_entry(&sd_ctl_dir[0].child);
5356}
5338#else 5357#else
5339static void init_sched_domain_sysctl(void) 5358static void register_sched_domain_sysctl(void)
5359{
5360}
5361static void unregister_sched_domain_sysctl(void)
5340{ 5362{
5341} 5363}
5342#endif 5364#endif
@@ -6271,6 +6293,8 @@ static int arch_init_sched_domains(const cpumask_t *cpu_map)
6271 6293
6272 err = build_sched_domains(&cpu_default_map); 6294 err = build_sched_domains(&cpu_default_map);
6273 6295
6296 register_sched_domain_sysctl();
6297
6274 return err; 6298 return err;
6275} 6299}
6276 6300
@@ -6287,6 +6311,8 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
6287{ 6311{
6288 int i; 6312 int i;
6289 6313
6314 unregister_sched_domain_sysctl();
6315
6290 for_each_cpu_mask(i, *cpu_map) 6316 for_each_cpu_mask(i, *cpu_map)
6291 cpu_attach_domain(NULL, i); 6317 cpu_attach_domain(NULL, i);
6292 synchronize_sched(); 6318 synchronize_sched();
@@ -6317,6 +6343,8 @@ int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
6317 if (!err && !cpus_empty(*partition2)) 6343 if (!err && !cpus_empty(*partition2))
6318 err = build_sched_domains(partition2); 6344 err = build_sched_domains(partition2);
6319 6345
6346 register_sched_domain_sysctl();
6347
6320 return err; 6348 return err;
6321} 6349}
6322 6350
@@ -6448,8 +6476,6 @@ void __init sched_init_smp(void)
6448 /* XXX: Theoretical race here - CPU may be hotplugged now */ 6476 /* XXX: Theoretical race here - CPU may be hotplugged now */
6449 hotcpu_notifier(update_sched_domains, 0); 6477 hotcpu_notifier(update_sched_domains, 0);
6450 6478
6451 init_sched_domain_sysctl();
6452
6453 /* Move init over to a non-isolated CPU */ 6479 /* Move init over to a non-isolated CPU */
6454 if (set_cpus_allowed(current, non_isolated_cpus) < 0) 6480 if (set_cpus_allowed(current, non_isolated_cpus) < 0)
6455 BUG(); 6481 BUG();