Commit 6382bc90 authored by Milton Miller's avatar Milton Miller Committed by Ingo Molnar

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: default avatarMilton Miller <miltonm@bga.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 97b6ea7b
...@@ -5250,6 +5250,18 @@ static struct ctl_table *sd_alloc_ctl_entry(int n) ...@@ -5250,6 +5250,18 @@ static struct ctl_table *sd_alloc_ctl_entry(int n)
return entry; return entry;
} }
static void sd_free_ctl_entry(struct ctl_table **tablep)
{
struct ctl_table *entry = *tablep;
for (entry = *tablep; entry->procname; entry++)
if (entry->child)
sd_free_ctl_entry(&entry->child);
kfree(*tablep);
*tablep = NULL;
}
static void static void
set_table_entry(struct ctl_table *entry, set_table_entry(struct ctl_table *entry,
const char *procname, void *data, int maxlen, const char *procname, void *data, int maxlen,
...@@ -5318,7 +5330,7 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu) ...@@ -5318,7 +5330,7 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
} }
static struct ctl_table_header *sd_sysctl_header; static struct ctl_table_header *sd_sysctl_header;
static void init_sched_domain_sysctl(void) static void register_sched_domain_sysctl(void)
{ {
int i, cpu_num = num_online_cpus(); int i, cpu_num = num_online_cpus();
struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1);
...@@ -5335,8 +5347,18 @@ static void init_sched_domain_sysctl(void) ...@@ -5335,8 +5347,18 @@ static void init_sched_domain_sysctl(void)
} }
sd_sysctl_header = register_sysctl_table(sd_ctl_root); sd_sysctl_header = register_sysctl_table(sd_ctl_root);
} }
static void unregister_sched_domain_sysctl(void)
{
unregister_sysctl_table(sd_sysctl_header);
sd_sysctl_header = NULL;
sd_free_ctl_entry(&sd_ctl_dir[0].child);
}
#else #else
static void init_sched_domain_sysctl(void) static void register_sched_domain_sysctl(void)
{
}
static void unregister_sched_domain_sysctl(void)
{ {
} }
#endif #endif
...@@ -6271,6 +6293,8 @@ static int arch_init_sched_domains(const cpumask_t *cpu_map) ...@@ -6271,6 +6293,8 @@ static int arch_init_sched_domains(const cpumask_t *cpu_map)
err = build_sched_domains(&cpu_default_map); err = build_sched_domains(&cpu_default_map);
register_sched_domain_sysctl();
return err; return err;
} }
...@@ -6287,6 +6311,8 @@ static void detach_destroy_domains(const cpumask_t *cpu_map) ...@@ -6287,6 +6311,8 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
{ {
int i; int i;
unregister_sched_domain_sysctl();
for_each_cpu_mask(i, *cpu_map) for_each_cpu_mask(i, *cpu_map)
cpu_attach_domain(NULL, i); cpu_attach_domain(NULL, i);
synchronize_sched(); synchronize_sched();
...@@ -6317,6 +6343,8 @@ int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2) ...@@ -6317,6 +6343,8 @@ int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
if (!err && !cpus_empty(*partition2)) if (!err && !cpus_empty(*partition2))
err = build_sched_domains(partition2); err = build_sched_domains(partition2);
register_sched_domain_sysctl();
return err; return err;
} }
...@@ -6448,8 +6476,6 @@ void __init sched_init_smp(void) ...@@ -6448,8 +6476,6 @@ void __init sched_init_smp(void)
/* XXX: Theoretical race here - CPU may be hotplugged now */ /* XXX: Theoretical race here - CPU may be hotplugged now */
hotcpu_notifier(update_sched_domains, 0); hotcpu_notifier(update_sched_domains, 0);
init_sched_domain_sysctl();
/* Move init over to a non-isolated CPU */ /* Move init over to a non-isolated CPU */
if (set_cpus_allowed(current, non_isolated_cpus) < 0) if (set_cpus_allowed(current, non_isolated_cpus) < 0)
BUG(); BUG();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment