diff -Nraup a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h 2004-10-18 05:11:39.000000000 -0700 +++ b/include/linux/sched.h 2004-10-25 00:09:49.247710304 -0700 @@ -1029,4 +1029,8 @@ extern long sched_getaffinity(pid_t pid, #endif /* __KERNEL__ */ +#ifdef CONFIG_SYSCTL +extern void init_sched_domain_sysctl(void); +extern void destroy_sched_domain_sysctl(void); +#endif /* CONFIG_SYSCTL */ #endif diff -Nraup a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c 2004-10-18 05:11:39.000000000 -0700 +++ b/kernel/sched.c 2004-10-25 00:10:17.048491213 -0700 @@ -4576,6 +4576,7 @@ __init static void arch_init_sched_domai #endif cpu_attach_domain(sd, i); } + init_sched_domain_sysctl(); } #undef SCHED_DOMAIN_DEBUG @@ -4767,3 +4768,132 @@ void __might_sleep(char *file, int line) } EXPORT_SYMBOL(__might_sleep); #endif + +#ifdef CONFIG_SYSCTL +static struct ctl_table sd_ctl_dir[] = { + {1, "sched_domain", NULL, 0, 0755, NULL, }, + {0,}, +}; + +static struct ctl_table sd_ctl_root[] = { + {1, "kernel", NULL, 0, 0755, sd_ctl_dir, }, + {0,}, +}; +__devinit static char *strdup(char *str) +{ + int n = strlen(str)+1; + char *s = kmalloc(n, GFP_KERNEL); + if (!s) return NULL; + return strcpy(s, str); +} +__devinit static struct ctl_table *sd_alloc_ctl_entry(int n) +{ + struct ctl_table *entry = (struct ctl_table *) + kmalloc(n * sizeof(struct ctl_table), GFP_KERNEL); + BUG_ON(!entry); + memset(entry, 0, n * sizeof(struct ctl_table)); + return entry; +} + +__devinit static void +set_table_entry(struct ctl_table *entry, int ctl_name, const char *procname, + void *data, int maxlen, mode_t mode, + proc_handler *proc_handler) +{ + entry->ctl_name = ctl_name; + entry->procname = procname; + entry->data = data; + entry->maxlen = maxlen; + entry->mode = mode; + entry->proc_handler = proc_handler; +} + +__devinit static struct ctl_table * +sd_alloc_ctl_domain_table(struct sched_domain *sd) +{ + struct ctl_table *table; + table = sd_alloc_ctl_entry(9); + + set_table_entry(&table[0], 1, "min_interval", &sd->min_interval, + sizeof(long), 0644, proc_doulongvec_minmax); + set_table_entry(&table[1], 2, "max_interval", &sd->max_interval, + sizeof(long), 0644, proc_doulongvec_minmax); + set_table_entry(&table[2], 3, "busy_factor", &sd->busy_factor, + sizeof(int), 0644, proc_dointvec_minmax); + set_table_entry(&table[3], 4, "imbalance_pct", &sd->imbalance_pct, + sizeof(int), 0644, proc_dointvec_minmax); + set_table_entry(&table[4], 5, "cache_hot_time", &sd->cache_hot_time, + sizeof(long long), 0644, proc_doulonglongvec_minmax); + set_table_entry(&table[5], 6, "cache_nice_tries", &sd->cache_nice_tries, + sizeof(int), 0644, proc_dointvec_minmax); + set_table_entry(&table[6], 7, "per_cpu_gain", &sd->per_cpu_gain, + sizeof(int), 0644, proc_dointvec_minmax); + set_table_entry(&table[7], 8, "flags", &sd->flags, + sizeof(int), 0644, proc_dointvec_minmax); + return table; +} + +__devinit static ctl_table *sd_alloc_ctl_cpu_table(int cpu) +{ + struct sched_domain *sd; + int domain_num = 0, i; + struct ctl_table *entry, *table; + char buf[32]; + for_each_domain(cpu, sd) + domain_num++; + entry = table = sd_alloc_ctl_entry(domain_num + 1); + + i = 0; + for_each_domain(cpu, sd) { + sprintf(buf, "domain-%d", i); + entry->ctl_name = i + 1; + entry->procname = strdup(buf); + entry->mode = 0755; + entry->child = sd_alloc_ctl_domain_table(sd); + entry++; + i++; + } + return table; +} + +static struct ctl_table_header *sd_sysctl_header; +__devinit void init_sched_domain_sysctl() +{ + int i, cpu_num = num_online_cpus(); + char buf[32]; + struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); + + sd_ctl_dir[0].child = entry; + + for (i = 0; i < cpu_num; i++, entry++) { + sprintf(buf, "cpu%d", i); + entry->ctl_name = i + 1; + entry->procname = strdup(buf); + entry->mode = 0755; + entry->child = sd_alloc_ctl_cpu_table(i); + } + sd_sysctl_header = register_sysctl_table(sd_ctl_root, 0); +} + +__devinit void destroy_sched_domain_sysctl() +{ + int cpu, cpu_num = num_online_cpus(); + struct sched_domain *sd; + struct ctl_table *root = sd_ctl_dir[0].child; + struct ctl_table *entry, *table; + + unregister_sysctl_table(sd_sysctl_header); + entry = root; + for (cpu = 0; cpu < cpu_num; cpu++, entry++) { + kfree(entry->procname); + table = entry->child; + for_each_domain(cpu, sd) { + kfree(table->procname); + kfree(table->child); + table++; + } + kfree(entry->child); + } + kfree(root); +} +#endif /* CONFIG_SYSCTL */