diff options
author | Nick Piggin <nickpiggin@yahoo.com.au> | 2007-07-26 07:40:43 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-07-26 07:40:43 -0400 |
commit | e692ab53473c93c0d0820618c97aa74a62ab67da (patch) | |
tree | ef3d3c85c02dfbdc54400ed1ada26e90aadad300 | |
parent | d02c7a8cf208eb80a3ccbff40a6bebe8902af35a (diff) |
[PATCH] sched: debug feature - make the sched-domains tree runtime-tweakable
debugging feature: make the sched-domains tree runtime-tweakable.
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ mingo@elte.hu: made it depend on CONFIG_SCHED_DEBUG & small updates ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/sched.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 3eed860cf292..5c51d7e5dcc1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/percpu.h> | 53 | #include <linux/percpu.h> |
54 | #include <linux/kthread.h> | 54 | #include <linux/kthread.h> |
55 | #include <linux/seq_file.h> | 55 | #include <linux/seq_file.h> |
56 | #include <linux/sysctl.h> | ||
56 | #include <linux/syscalls.h> | 57 | #include <linux/syscalls.h> |
57 | #include <linux/times.h> | 58 | #include <linux/times.h> |
58 | #include <linux/tsacct_kern.h> | 59 | #include <linux/tsacct_kern.h> |
@@ -5202,10 +5203,129 @@ static void migrate_dead_tasks(unsigned int dead_cpu) | |||
5202 | if (!next) | 5203 | if (!next) |
5203 | break; | 5204 | break; |
5204 | migrate_dead(dead_cpu, next); | 5205 | migrate_dead(dead_cpu, next); |
5206 | |||
5205 | } | 5207 | } |
5206 | } | 5208 | } |
5207 | #endif /* CONFIG_HOTPLUG_CPU */ | 5209 | #endif /* CONFIG_HOTPLUG_CPU */ |
5208 | 5210 | ||
5211 | #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL) | ||
5212 | |||
5213 | static struct ctl_table sd_ctl_dir[] = { | ||
5214 | {CTL_UNNUMBERED, "sched_domain", NULL, 0, 0755, NULL, }, | ||
5215 | {0,}, | ||
5216 | }; | ||
5217 | |||
5218 | static struct ctl_table sd_ctl_root[] = { | ||
5219 | {CTL_UNNUMBERED, "kernel", NULL, 0, 0755, sd_ctl_dir, }, | ||
5220 | {0,}, | ||
5221 | }; | ||
5222 | |||
5223 | static struct ctl_table *sd_alloc_ctl_entry(int n) | ||
5224 | { | ||
5225 | struct ctl_table *entry = | ||
5226 | kmalloc(n * sizeof(struct ctl_table), GFP_KERNEL); | ||
5227 | |||
5228 | BUG_ON(!entry); | ||
5229 | memset(entry, 0, n * sizeof(struct ctl_table)); | ||
5230 | |||
5231 | return entry; | ||
5232 | } | ||
5233 | |||
5234 | static void | ||
5235 | set_table_entry(struct ctl_table *entry, int ctl_name, | ||
5236 | const char *procname, void *data, int maxlen, | ||
5237 | mode_t mode, proc_handler *proc_handler) | ||
5238 | { | ||
5239 | entry->ctl_name = ctl_name; | ||
5240 | entry->procname = procname; | ||
5241 | entry->data = data; | ||
5242 | entry->maxlen = maxlen; | ||
5243 | entry->mode = mode; | ||
5244 | entry->proc_handler = proc_handler; | ||
5245 | } | ||
5246 | |||
5247 | static struct ctl_table * | ||
5248 | sd_alloc_ctl_domain_table(struct sched_domain *sd) | ||
5249 | { | ||
5250 | struct ctl_table *table = sd_alloc_ctl_entry(14); | ||
5251 | |||
5252 | set_table_entry(&table[0], 1, "min_interval", &sd->min_interval, | ||
5253 | sizeof(long), 0644, proc_doulongvec_minmax); | ||
5254 | set_table_entry(&table[1], 2, "max_interval", &sd->max_interval, | ||
5255 | sizeof(long), 0644, proc_doulongvec_minmax); | ||
5256 | set_table_entry(&table[2], 3, "busy_idx", &sd->busy_idx, | ||
5257 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5258 | set_table_entry(&table[3], 4, "idle_idx", &sd->idle_idx, | ||
5259 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5260 | set_table_entry(&table[4], 5, "newidle_idx", &sd->newidle_idx, | ||
5261 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5262 | set_table_entry(&table[5], 6, "wake_idx", &sd->wake_idx, | ||
5263 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5264 | set_table_entry(&table[6], 7, "forkexec_idx", &sd->forkexec_idx, | ||
5265 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5266 | set_table_entry(&table[7], 8, "busy_factor", &sd->busy_factor, | ||
5267 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5268 | set_table_entry(&table[8], 9, "imbalance_pct", &sd->imbalance_pct, | ||
5269 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5270 | set_table_entry(&table[9], 10, "cache_hot_time", &sd->cache_hot_time, | ||
5271 | sizeof(long long), 0644, proc_doulongvec_minmax); | ||
5272 | set_table_entry(&table[10], 11, "cache_nice_tries", | ||
5273 | &sd->cache_nice_tries, | ||
5274 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5275 | set_table_entry(&table[12], 13, "flags", &sd->flags, | ||
5276 | sizeof(int), 0644, proc_dointvec_minmax); | ||
5277 | |||
5278 | return table; | ||
5279 | } | ||
5280 | |||
5281 | static ctl_table *sd_alloc_ctl_cpu_table(int cpu) | ||
5282 | { | ||
5283 | struct ctl_table *entry, *table; | ||
5284 | struct sched_domain *sd; | ||
5285 | int domain_num = 0, i; | ||
5286 | char buf[32]; | ||
5287 | |||
5288 | for_each_domain(cpu, sd) | ||
5289 | domain_num++; | ||
5290 | entry = table = sd_alloc_ctl_entry(domain_num + 1); | ||
5291 | |||
5292 | i = 0; | ||
5293 | for_each_domain(cpu, sd) { | ||
5294 | snprintf(buf, 32, "domain%d", i); | ||
5295 | entry->ctl_name = i + 1; | ||
5296 | entry->procname = kstrdup(buf, GFP_KERNEL); | ||
5297 | entry->mode = 0755; | ||
5298 | entry->child = sd_alloc_ctl_domain_table(sd); | ||
5299 | entry++; | ||
5300 | i++; | ||
5301 | } | ||
5302 | return table; | ||
5303 | } | ||
5304 | |||
5305 | static struct ctl_table_header *sd_sysctl_header; | ||
5306 | static void init_sched_domain_sysctl(void) | ||
5307 | { | ||
5308 | int i, cpu_num = num_online_cpus(); | ||
5309 | struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); | ||
5310 | char buf[32]; | ||
5311 | |||
5312 | sd_ctl_dir[0].child = entry; | ||
5313 | |||
5314 | for (i = 0; i < cpu_num; i++, entry++) { | ||
5315 | snprintf(buf, 32, "cpu%d", i); | ||
5316 | entry->ctl_name = i + 1; | ||
5317 | entry->procname = kstrdup(buf, GFP_KERNEL); | ||
5318 | entry->mode = 0755; | ||
5319 | entry->child = sd_alloc_ctl_cpu_table(i); | ||
5320 | } | ||
5321 | sd_sysctl_header = register_sysctl_table(sd_ctl_root); | ||
5322 | } | ||
5323 | #else | ||
5324 | static void init_sched_domain_sysctl(void) | ||
5325 | { | ||
5326 | } | ||
5327 | #endif | ||
5328 | |||
5209 | /* | 5329 | /* |
5210 | * migration_call - callback that gets triggered when a CPU is added. | 5330 | * migration_call - callback that gets triggered when a CPU is added. |
5211 | * Here we can start up the necessary migration thread for the new CPU. | 5331 | * Here we can start up the necessary migration thread for the new CPU. |
@@ -6311,6 +6431,8 @@ void __init sched_init_smp(void) | |||
6311 | /* XXX: Theoretical race here - CPU may be hotplugged now */ | 6431 | /* XXX: Theoretical race here - CPU may be hotplugged now */ |
6312 | hotcpu_notifier(update_sched_domains, 0); | 6432 | hotcpu_notifier(update_sched_domains, 0); |
6313 | 6433 | ||
6434 | init_sched_domain_sysctl(); | ||
6435 | |||
6314 | /* Move init over to a non-isolated CPU */ | 6436 | /* Move init over to a non-isolated CPU */ |
6315 | if (set_cpus_allowed(current, non_isolated_cpus) < 0) | 6437 | if (set_cpus_allowed(current, non_isolated_cpus) < 0) |
6316 | BUG(); | 6438 | BUG(); |